feat(panel and auth): fix study panel to not rely on priors and add token param to url (#3381)
* fix: multiframe * fix the unnecessary use of prior since some servers dont like it * add authentication via token in url * add data citation * add resources * upgrade packages * yarn lock * apply review comments
This commit is contained in:
parent
cba57a1b65
commit
84cb709b44
144
DATACITATION.md
Normal file
144
DATACITATION.md
Normal file
@ -0,0 +1,144 @@
|
||||
# OHIF public demo data sets
|
||||
|
||||
The OHIF Viewer's public demo page, available at https://viewer.ohif.org/, uses publicly anonymized demo datasets.
|
||||
These datasets were mostly obtained from the [NIH NCI Imaging Data Commons](https://datacommons.cancer.gov/repository/imaging-data-commons)
|
||||
and [NIH NCI TCIA](https://www.cancerimagingarchive.net/). Before listing the datasets,
|
||||
we would like to extend a special thank you to all groups who have made their datasets publicly available.
|
||||
Without them, we would not have been able to create this demo page.
|
||||
|
||||
Please find below the list of datasets used on the demo page, along with their respective citations.
|
||||
|
||||
|
||||
## Platforms
|
||||
### NIH NCI IDC
|
||||
|
||||
- Fedorov, A., Longabaugh, W.J., Pot, D., Clunie, D.A., Pieper, S., Aerts, H.J., Homeyer, A., Lewis, R., Akbarzadeh, A., Bontempi, D. and Clifford, W., 2021. NCI imaging data commons. Cancer research, 81(16), p.4188.
|
||||
|
||||
### NIH NCI TCIA
|
||||
|
||||
- Clark, K., Vendt, B., Smith, K., Freymann, J., Kirby, J., Koppel, P., Moore, S., Phillips, S., Maffitt, D., Pringle, M., Tarbox, L., & Prior, F. (2013). The Cancer Imaging Archive (TCIA): Maintaining and Operating a Public Information Repository. Journal of Digital Imaging, 26(6), 1045–1057. https://doi.org/10.1007/s10278-013-9622-7
|
||||
|
||||
|
||||
|
||||
|
||||
## Datasets
|
||||
Below you can find the StudyInstanceUID of the studies that are used in the demo page along with their citations.
|
||||
|
||||
### 1.3.6.1.4.1.14519.5.2.1.267424821384663813780850856506829388886
|
||||
|
||||
Segmentation of Vestibular Schwannoma from Magnetic Resonance Imaging: An Open Annotated Dataset and Baseline Algorithm (Vestibular-Schwannoma-SEG)
|
||||
|
||||
- Shapey, J., Kujawa, A., Dorent, R., Wang, G., Bisdas, S., Dimitriadis, A., Grishchuck, D., Paddick, I., Kitchen, N., Bradford, R., Saeed, S., Ourselin, S., & Vercauteren, T. (2021). Segmentation of Vestibular Schwannoma from Magnetic Resonance Imaging: An Open Annotated Dataset and Baseline Algorithm [Data set]. The Cancer Imaging Archive. https://doi.org/10.7937/TCIA.9YTJ-5Q73
|
||||
|
||||
- Shapey, J., Kujawa, A., Dorent, R., Wang, G., Dimitriadis, A., Grishchuk, D., Paddick, I., Kitchen, N., Bradford, R., Saeed, S. R., Bisdas, S., Ourselin, S., & Vercauteren, T. (2021). Segmentation of vestibular schwannoma from MRI, an open annotated dataset and baseline algorithm. In Scientific Data (Vol. 8, Issue 1). Springer Science and Business Media LLC. https://doi.org/10.1038/s41597-021-01064-w
|
||||
|
||||
|
||||
### 1.3.6.1.4.1.14519.5.2.1.7009.2403.334240657131972136850343327463
|
||||
### 1.3.6.1.4.1.14519.5.2.1.7009.2403.871108593056125491804754960339
|
||||
|
||||
|
||||
ACRIN-NSCLC-FDG-PET (ACRIN 6668)
|
||||
|
||||
- Kinahan, P., Muzi, M., Bialecki, B., Herman, B., & Coombs, L. (2019). Data from the ACRIN 6668 Trial NSCLC-FDG-PET (Version 2) [Data set]. The Cancer Imaging Archive. https://doi.org/10.7937/tcia.2019.30ilqfcl
|
||||
|
||||
- Machtay, M., Duan, F., Siegel, B. A., Snyder, B. S., Gorelick, J. J., Reddin, J. S., Munden, R., Johnson, D. W., Wilf, L. H., DeNittis, A., Sherwin, N., Cho, K. H., Kim, S., Videtic, G., Neumann, D. R., Komaki, R., Macapinlac, H., Bradley, J. D., & Alavi, A. (2013). Prediction of Survival by [18F]Fluorodeoxyglucose Positron Emission Tomography in Patients With Locally Advanced Non–Small-Cell Lung Cancer Undergoing Definitive Chemoradiation Therapy: Results of the ACRIN 6668/RTOG 0235 Trial. In Journal of Clinical Oncology (Vol. 31, Issue 30, pp. 3823–3830). American Society of Clinical Oncology (ASCO). https://doi.org/10.1200/jco.2012.47.5947
|
||||
|
||||
|
||||
### 2.25.103659964951665749659160840573802789777
|
||||
|
||||
The Cancer Genome Atlas Glioblastoma Multiforme Collection (TCGA-GBM)
|
||||
|
||||
- Scarpace, L., Mikkelsen, T., Cha, S., Rao, S., Tekchandani, S., Gutman, D., Saltz, J. H., Erickson, B. J., Pedano, N., Flanders, A. E., Barnholtz-Sloan, J., Ostrom, Q., Barboriak, D., & Pierce, L. J. (2016). The Cancer Genome Atlas Glioblastoma Multiforme Collection (TCGA-GBM) (Version 4) [Data set]. The Cancer Imaging Archive. https://doi.org/10.7937/K9/TCIA.2016.RNYFUYE9
|
||||
|
||||
|
||||
### 1.3.6.1.4.1.14519.5.2.1.256467663913010332776401703474716742458
|
||||
|
||||
Abdominal or pelvic enhanced CT images within 10 days before surgery of 230 patients with stage II colorectal cancer (StageII-Colorectal-CT)
|
||||
|
||||
|
||||
- Tong T., Li M. (2022) Abdominal or pelvic enhanced CT images within 10 days before surgery of 230 patients with stage II colorectal cancer (StageII-Colorectal-CT) [Dataset]. The Cancer Imaging Archive. DOI: https://doi.org/10.7937/p5k5-tg43
|
||||
|
||||
- Li, M., Gong, J., Bao, Y., Huang, D., Peng, J., & Tong, T. (2022). Special issue “The advance of solid tumor research in China”: Prognosis prediction for stage II colorectal cancer by fusing computed tomography radiomics and deep‐learning features of primary lesions and peripheral lymph nodes. In International Journal of Cancer. Wiley. https://doi.org/10.1002/ijc.34053
|
||||
|
||||
|
||||
### 1.3.6.1.4.1.14519.5.2.1.3023.4024.215308722288168917637555384485
|
||||
|
||||
The Cancer Genome Atlas Sarcoma Collection (TCGA-SARC)
|
||||
|
||||
- Roche, C., Bonaccio, E., & Filippini, J. (2016). The Cancer Genome Atlas Sarcoma Collection (TCGA-SARC) (Version 3) [Data set]. The Cancer Imaging Archive. https://doi.org/10.7937/K9/TCIA.2016.CX6YLSUX
|
||||
|
||||
|
||||
|
||||
### 1.3.6.1.4.1.14519.5.2.1.4792.2001.105216574054253895819671475627
|
||||
|
||||
BREAST-DIAGNOSIS
|
||||
|
||||
|
||||
- Bloch, B. Nicolas, Jain, Ashali, & Jaffe, C. Carl. (2015). BREAST-DIAGNOSIS [Data set]. The Cancer Imaging Archive. http://doi.org/10.7937/K9/TCIA.2015.SDNRQXXR
|
||||
|
||||
|
||||
|
||||
|
||||
### 1.3.6.1.4.1.14519.5.2.1.1706.8374.643249677828306008300337414785
|
||||
|
||||
Multimodality annotated HCC cases with and without advanced imaging segmentation (HCC-TACE-Seg)
|
||||
|
||||
|
||||
- Moawad, A. W., Fuentes, D., Morshid, A., Khalaf, A. M., Elmohr, M. M., Abusaif, A., Hazle, J. D., Kaseb, A. O., Hassan, M., Mahvash, A., Szklaruk, J., Qayyom, A., & Elsayes, K. (2021). Multimodality annotated HCC cases with and without advanced imaging segmentation [Data set]. The Cancer Imaging Archive. https://doi.org/10.7937/TCIA.5FNA-0924
|
||||
|
||||
- Morshid, A., Elsayes, K. M., Khalaf, A. M., Elmohr, M. M., Yu, J., Kaseb, A. O., Hassan, M., Mahvash, A., Wang, Z., Hazle, J. D., & Fuentes, D. (2019). A Machine Learning Model to Predict Hepatocellular Carcinoma Response to Transcatheter Arterial Chemoembolization. Radiology: Artificial Intelligence, 1(5), e180021. https://doi.org/10.1148/ryai.2019180021
|
||||
|
||||
|
||||
|
||||
### 1.3.6.1.4.1.14519.5.2.1.1188.2803.137585363493444318569098508293
|
||||
|
||||
Ultrasound data of a variety of liver masses (B-mode-and-CEUS-Liver)
|
||||
|
||||
- Eisenbrey, J., Lyshchik, A., & Wessner, C. (2021). Ultrasound data of a variety of liver masses [Data set]. The Cancer Imaging Archive. DOI: https://doi.org/10.7937/TCIA.2021.v4z7-tc39
|
||||
|
||||
|
||||
|
||||
### 1.3.6.1.4.1.32722.99.99.62087908186665265759322018723889952421
|
||||
|
||||
NSCLC-Radiomics
|
||||
|
||||
- Aerts, H. J. W. L., Wee, L., Rios Velazquez, E., Leijenaar, R. T. H., Parmar, C., Grossmann, P., Carvalho, S., Bussink, J., Monshouwer, R., Haibe-Kains, B., Rietveld, D., Hoebers, F., Rietbergen, M. M., Leemans, C. R., Dekker, A., Quackenbush, J., Gillies, R. J., Lambin, P. (2019). Data From NSCLC-Radiomics (version 4) [Data set]. The Cancer Imaging Archive. https://doi.org/10.7937/K9/TCIA.2015.PF0M9REI
|
||||
|
||||
|
||||
- Aerts, H. J. W. L., Velazquez, E. R., Leijenaar, R. T. H., Parmar, C., Grossmann, P., Carvalho, S., Bussink, J., Monshouwer, R., Haibe-Kains, B., Rietveld, D., Hoebers, F., Rietbergen, M. M., Leemans, C. R., Dekker, A., Quackenbush, J., Gillies, R. J., Lambin, P. (2014, June 3). Decoding tumour phenotype by noninvasive imaging using a quantitative radiomics approach. Nature Communications. Nature Publishing Group. https://doi.org/10.1038/ncomms5006 (link)
|
||||
|
||||
|
||||
### 1.3.6.1.4.1.14519.5.2.1.3671.4754.298665348758363466150039312520
|
||||
|
||||
QIN-PROSTATE-Repeatability
|
||||
|
||||
- Fedorov, A; Schwier, M; Clunie, D; Herz, C; Pieper, S; Kikinis, R; Tempany, C; Fennessy, F. (2018). Data From QIN-PROSTATE-Repeatability. The Cancer Imaging Archive. DOI: 10.7937/K9/TCIA.2018.MR1CKGND
|
||||
|
||||
|
||||
- Fedorov A, Vangel MG, Tempany CM, Fennessy FM. Multiparametric Magnetic Resonance Imaging of the Prostate: Repeatability of Volume and Apparent Diffusion Coefficient Quantification. Investigative Radiology. 52, 538–546 (2017). DOI: 10.1097/RLI.0000000000000382
|
||||
|
||||
- Fedorov, A., Schwier, M., Clunie, D., Herz, C., Pieper, S., Kikinis,R., Tempany, C. & Fennessy, F. An annotated test-retest collection of prostate multiparametric MRI. Scientific Data 5, 180281 (2018). DOI:
|
||||
|
||||
### 2.25.141277760791347900862109212450152067508
|
||||
|
||||
The Clinical Proteomic Tumor Analysis Consortium Clear Cell Renal Cell Carcinoma Collection (CPTAC-CCRCC)
|
||||
|
||||
- National Cancer Institute Clinical Proteomic Tumor Analysis Consortium (CPTAC). (2018). The Clinical Proteomic Tumor Analysis Consortium Clear Cell Renal Cell Carcinoma Collection (CPTAC-CCRCC) (Version 10) [Data set]. The Cancer Imaging Archive. https://doi.org/10.7937/K9/TCIA.2018.OBLAMN27
|
||||
|
||||
- The CPTAC program requests that publications using data from this program include the following statement: “Data used in this publication were generated by the National Cancer Institute Clinical Proteomic Tumor Analysis Consortium (CPTAC).”
|
||||
|
||||
|
||||
### 2.25.275741864483510678566144889372061815320
|
||||
|
||||
National Lung Screening Trial
|
||||
|
||||
- National Lung Screening Trial Research Team. (2013). Data from the National Lung Screening Trial (NLST) [Data set]. The Cancer Imaging Archive. https://doi.org/10.7937/TCIA.HMQ8-J677
|
||||
|
||||
- National Lung Screening Trial Research Team*; Aberle DR, Adams AM, Berg CD, Black WC, Clapp JD, Fagerstrom RM, Gareen IF, Gatsonis C, Marcus PM, Sicks JD (2011). Reduced Lung-Cancer Mortality with Low-Dose Computed Tomographic Screening. New England Journal of Medicine, 365(5), 395–409. https://doi.org/10.1056/nejmoa1102873
|
||||
|
||||
|
||||
### 1.3.6.1.4.1.14519.5.2.1.99.1071.26968527900428638961173806140069
|
||||
|
||||
Stony Brook University COVID-19 Positive Cases (COVID-19-NY-SBU)
|
||||
|
||||
- Saltz, J., Saltz, M., Prasanna, P., Moffitt, R., Hajagos, J., Bremer, E., Balsamo, J., & Kurc, T. (2021). Stony Brook University COVID-19 Positive Cases [Data set]. The Cancer Imaging Archive. https://doi.org/10.7937/TCIA.BBAG-2923
|
||||
@ -46,7 +46,7 @@
|
||||
"@babel/runtime": "^7.20.13",
|
||||
"classnames": "^2.3.2",
|
||||
"@cornerstonejs/adapters": "^0.6.0",
|
||||
"@cornerstonejs/core": "^0.44.2",
|
||||
"@cornerstonejs/tools": "^0.66.2"
|
||||
"@cornerstonejs/core": "^0.46.2",
|
||||
"@cornerstonejs/tools": "^0.67.2"
|
||||
}
|
||||
}
|
||||
|
||||
@ -34,7 +34,7 @@
|
||||
"peerDependencies": {
|
||||
"@ohif/core": "^3.0.0",
|
||||
"@ohif/ui": "^2.0.0",
|
||||
"@cornerstonejs/dicom-image-loader": "^0.4.0",
|
||||
"@cornerstonejs/dicom-image-loader": "^0.6.4",
|
||||
"@cornerstonejs/codec-charls": "^1.2.3",
|
||||
"@cornerstonejs/codec-libjpeg-turbo-8bit": "^1.2.2",
|
||||
"@cornerstonejs/codec-openjpeg": "^1.2.2",
|
||||
@ -53,9 +53,9 @@
|
||||
"dependencies": {
|
||||
"@babel/runtime": "^7.20.13",
|
||||
"@cornerstonejs/adapters": "^0.6.0",
|
||||
"@cornerstonejs/core": "^0.44.2",
|
||||
"@cornerstonejs/streaming-image-volume-loader": "^0.19.2",
|
||||
"@cornerstonejs/tools": "^0.66.2",
|
||||
"@cornerstonejs/core": "^0.46.2",
|
||||
"@cornerstonejs/streaming-image-volume-loader": "^0.20.2",
|
||||
"@cornerstonejs/tools": "^0.67.2",
|
||||
"@kitware/vtk.js": "27.3.1",
|
||||
"html2canvas": "^1.4.1",
|
||||
"lodash.debounce": "4.0.8",
|
||||
|
||||
@ -23,6 +23,7 @@ import * as CornerstoneExtensionTypes from './types';
|
||||
import { toolNames } from './initCornerstoneTools';
|
||||
import { getEnabledElement, reset as enabledElementReset } from './state';
|
||||
import dicomLoaderService from './utils/dicomLoaderService';
|
||||
import getActiveViewportEnabledElement from './utils/getActiveViewportEnabledElement';
|
||||
import { registerColormap } from './utils/colormap/transferFunctionHelpers';
|
||||
|
||||
import { id } from './id';
|
||||
@ -141,5 +142,5 @@ const cornerstoneExtension: Types.Extensions.Extension = {
|
||||
};
|
||||
|
||||
export type { PublicViewportOptions };
|
||||
export { measurementMappingUtils, CornerstoneExtensionTypes, toolNames };
|
||||
export { measurementMappingUtils, CornerstoneExtensionTypes, toolNames , getActiveViewportEnabledElement};
|
||||
export default cornerstoneExtension;
|
||||
|
||||
@ -200,6 +200,7 @@ function createDicomLocalApi(dicomLocalConfig) {
|
||||
displaySet.images.forEach(instance => {
|
||||
const NumberOfFrames = instance.NumberOfFrames;
|
||||
if (NumberOfFrames > 1) {
|
||||
// in multiframe we start at frame 1
|
||||
for (let i = 1; i <= NumberOfFrames; i++) {
|
||||
const imageId = this.getImageIdsForInstance({
|
||||
instance,
|
||||
|
||||
@ -12,7 +12,7 @@ const { sortStudyInstances, formatDate } = utils;
|
||||
function PanelStudyBrowser({
|
||||
servicesManager,
|
||||
getImageSrc,
|
||||
getStudiesForPatientByStudyInstanceUID,
|
||||
getStudiesForPatientByMRN,
|
||||
requestDisplaySetCreationForStudy,
|
||||
dataSource,
|
||||
}) {
|
||||
@ -64,12 +64,24 @@ function PanelStudyBrowser({
|
||||
useEffect(() => {
|
||||
// Fetch all studies for the patient in each primary study
|
||||
async function fetchStudiesForPatient(StudyInstanceUID) {
|
||||
const qidoStudiesForPatient =
|
||||
(await getStudiesForPatientByStudyInstanceUID(StudyInstanceUID)) || [];
|
||||
// current study qido
|
||||
const qidoForStudyUID = await dataSource.query.studies.search({
|
||||
studyInstanceUid: StudyInstanceUID,
|
||||
});
|
||||
|
||||
let qidoStudiesForPatient = qidoForStudyUID;
|
||||
|
||||
// try to fetch the prior studies based on the patientID if the
|
||||
// server can respond.
|
||||
try {
|
||||
qidoStudiesForPatient = await getStudiesForPatientByMRN(
|
||||
qidoForStudyUID
|
||||
);
|
||||
} catch (error) {
|
||||
console.warn(error);
|
||||
}
|
||||
|
||||
// TODO: This should be "naturalized DICOM JSON" studies
|
||||
const mappedStudies = _mapDataSourceStudies(qidoStudiesForPatient);
|
||||
|
||||
const actuallyMappedStudies = mappedStudies.map(qidoStudy => {
|
||||
return {
|
||||
studyInstanceUid: qidoStudy.StudyInstanceUID,
|
||||
@ -77,29 +89,27 @@ function PanelStudyBrowser({
|
||||
description: qidoStudy.StudyDescription,
|
||||
modalities: qidoStudy.ModalitiesInStudy,
|
||||
numInstances: qidoStudy.NumInstances,
|
||||
// displaySets: []
|
||||
};
|
||||
});
|
||||
if (isMounted.current) {
|
||||
setStudyDisplayList(prevArray => {
|
||||
const ret = [...prevArray];
|
||||
for (const study of actuallyMappedStudies) {
|
||||
if (
|
||||
!prevArray.find(
|
||||
it => it.studyInstanceUid === study.studyInstanceUid
|
||||
)
|
||||
) {
|
||||
ret.push(study);
|
||||
}
|
||||
|
||||
setStudyDisplayList(prevArray => {
|
||||
const ret = [...prevArray];
|
||||
for (const study of actuallyMappedStudies) {
|
||||
if (
|
||||
!prevArray.find(
|
||||
it => it.studyInstanceUid === study.studyInstanceUid
|
||||
)
|
||||
) {
|
||||
ret.push(study);
|
||||
}
|
||||
return ret;
|
||||
});
|
||||
}
|
||||
}
|
||||
return ret;
|
||||
});
|
||||
}
|
||||
|
||||
StudyInstanceUIDs.forEach(sid => fetchStudiesForPatient(sid));
|
||||
// eslint-disable-next-line react-hooks/exhaustive-deps
|
||||
}, [StudyInstanceUIDs, getStudiesForPatientByStudyInstanceUID]);
|
||||
}, [StudyInstanceUIDs, getStudiesForPatientByMRN]);
|
||||
|
||||
// // ~~ Initial Thumbnails
|
||||
useEffect(() => {
|
||||
@ -254,7 +264,7 @@ PanelStudyBrowser.propTypes = {
|
||||
getImageIdsForDisplaySet: PropTypes.func.isRequired,
|
||||
}).isRequired,
|
||||
getImageSrc: PropTypes.func.isRequired,
|
||||
getStudiesForPatientByStudyInstanceUID: PropTypes.func.isRequired,
|
||||
getStudiesForPatientByMRN: PropTypes.func.isRequired,
|
||||
requestDisplaySetCreationForStudy: PropTypes.func.isRequired,
|
||||
};
|
||||
|
||||
|
||||
@ -3,7 +3,7 @@ import PropTypes from 'prop-types';
|
||||
//
|
||||
import PanelStudyBrowser from './PanelStudyBrowser';
|
||||
import getImageSrcFromImageId from './getImageSrcFromImageId';
|
||||
import getStudiesForPatientByStudyInstanceUID from './getStudiesForPatientByStudyInstanceUID';
|
||||
import getStudiesForPatientByMRN from './getStudiesForPatientByMRN';
|
||||
import requestDisplaySetCreationForStudy from './requestDisplaySetCreationForStudy';
|
||||
|
||||
/**
|
||||
@ -21,7 +21,7 @@ function WrappedPanelStudyBrowser({
|
||||
// TODO: This should be made available a different way; route should have
|
||||
// already determined our datasource
|
||||
const dataSource = extensionManager.getDataSources()[0];
|
||||
const _getStudiesForPatientByStudyInstanceUID = getStudiesForPatientByStudyInstanceUID.bind(
|
||||
const _getStudiesForPatientByMRN = getStudiesForPatientByMRN.bind(
|
||||
null,
|
||||
dataSource
|
||||
);
|
||||
@ -38,9 +38,7 @@ function WrappedPanelStudyBrowser({
|
||||
servicesManager={servicesManager}
|
||||
dataSource={dataSource}
|
||||
getImageSrc={_getImageSrcFromImageId}
|
||||
getStudiesForPatientByStudyInstanceUID={
|
||||
_getStudiesForPatientByStudyInstanceUID
|
||||
}
|
||||
getStudiesForPatientByMRN={_getStudiesForPatientByMRN}
|
||||
requestDisplaySetCreationForStudy={_requestDisplaySetCreationForStudy}
|
||||
/>
|
||||
);
|
||||
|
||||
@ -6,7 +6,7 @@ function getImageSrcFromImageId(cornerstone, imageId) {
|
||||
return new Promise((resolve, reject) => {
|
||||
const canvas = document.createElement('canvas');
|
||||
cornerstone.utilities
|
||||
.loadImageToCanvas(canvas, imageId)
|
||||
.loadImageToCanvas({ canvas, imageId })
|
||||
.then(imageId => {
|
||||
resolve(canvas.toDataURL());
|
||||
})
|
||||
|
||||
11
extensions/default/src/Panels/getStudiesForPatientByMRN.js
Normal file
11
extensions/default/src/Panels/getStudiesForPatientByMRN.js
Normal file
@ -0,0 +1,11 @@
|
||||
async function getStudiesForPatientByMRN(dataSource, qidoForStudyUID) {
|
||||
if (qidoForStudyUID && qidoForStudyUID.length && qidoForStudyUID[0].mrn) {
|
||||
return dataSource.query.studies.search({
|
||||
patientId: qidoForStudyUID[0].mrn,
|
||||
});
|
||||
}
|
||||
console.log('No mrn found for', qidoForStudyUID);
|
||||
return qidoForStudyUID;
|
||||
}
|
||||
|
||||
export default getStudiesForPatientByMRN;
|
||||
@ -1,29 +0,0 @@
|
||||
async function getStudiesForPatientByStudyInstanceUID(
|
||||
dataSource,
|
||||
StudyInstanceUID
|
||||
) {
|
||||
if (StudyInstanceUID === undefined) {
|
||||
return;
|
||||
}
|
||||
// TODO: The `DicomMetadataStore` should short-circuit both of these requests
|
||||
// Data _could_ be here from route query, or if using JSON data source
|
||||
// We could also force this to "await" these values being available in the DICOMStore?
|
||||
// Kind of like promise fulfillment in @cornerstonejs/dicom-image-loader when there are multiple
|
||||
// outgoing requests for the same data
|
||||
const getStudyResult = await dataSource.query.studies.search({
|
||||
studyInstanceUid: StudyInstanceUID,
|
||||
});
|
||||
|
||||
// TODO: To Erik's point, the data source likely shouldn't deviate from
|
||||
// Naturalized DICOM JSON when returning. It makes things like this awkward (mrn)
|
||||
if (getStudyResult && getStudyResult.length && getStudyResult[0].mrn) {
|
||||
return dataSource.query.studies.search({
|
||||
patientId: getStudyResult[0].mrn,
|
||||
});
|
||||
}
|
||||
console.log('No mrn found for', getStudyResult);
|
||||
// The original study we KNOW belongs to the same set, so just return it
|
||||
return getStudyResult;
|
||||
}
|
||||
|
||||
export default getStudiesForPatientByStudyInstanceUID;
|
||||
@ -7,7 +7,7 @@ import getSopClassHandlerModule from './getSopClassHandlerModule.js';
|
||||
import getToolbarModule from './getToolbarModule';
|
||||
import getCommandsModule from './commandsModule';
|
||||
import getHangingProtocolModule from './getHangingProtocolModule';
|
||||
import getStudiesForPatientByStudyInstanceUID from './Panels/getStudiesForPatientByStudyInstanceUID';
|
||||
import getStudiesForPatientByMRN from './Panels/getStudiesForPatientByMRN';
|
||||
import getCustomizationModule from './getCustomizationModule';
|
||||
import { id } from './id.js';
|
||||
import preRegistration from './init';
|
||||
@ -34,7 +34,7 @@ const defaultExtension: Types.Extensions.Extension = {
|
||||
{
|
||||
name: 'common',
|
||||
exports: {
|
||||
getStudiesForPatientByStudyInstanceUID,
|
||||
getStudiesForPatientByMRN,
|
||||
},
|
||||
},
|
||||
];
|
||||
@ -45,4 +45,8 @@ const defaultExtension: Types.Extensions.Extension = {
|
||||
|
||||
export default defaultExtension;
|
||||
|
||||
export { ContextMenuController, CustomizeableContextMenuTypes };
|
||||
export {
|
||||
ContextMenuController,
|
||||
CustomizeableContextMenuTypes,
|
||||
getStudiesForPatientByMRN,
|
||||
};
|
||||
|
||||
@ -32,8 +32,8 @@
|
||||
"peerDependencies": {
|
||||
"@ohif/core": "^3.0.0",
|
||||
"classnames": "^2.3.2",
|
||||
"@cornerstonejs/core": "^0.44.2",
|
||||
"@cornerstonejs/tools": "^0.66.2",
|
||||
"@cornerstonejs/core": "^0.46.2",
|
||||
"@cornerstonejs/tools": "^0.67.2",
|
||||
"@ohif/extension-cornerstone-dicom-sr": "^3.0.0",
|
||||
"dcmjs": "^0.29.5",
|
||||
"lodash.debounce": "^4.17.21",
|
||||
|
||||
@ -18,7 +18,7 @@ const { formatDate } = utils;
|
||||
function PanelStudyBrowserTracking({
|
||||
servicesManager,
|
||||
getImageSrc,
|
||||
getStudiesForPatientByStudyInstanceUID,
|
||||
getStudiesForPatientByMRN,
|
||||
requestDisplaySetCreationForStudy,
|
||||
dataSource,
|
||||
}) {
|
||||
@ -76,8 +76,6 @@ function PanelStudyBrowserTracking({
|
||||
const activeViewportDisplaySetInstanceUIDs =
|
||||
viewports[activeViewportIndex]?.displaySetInstanceUIDs;
|
||||
|
||||
const isSingleViewport = numCols === 1 && numRows === 1;
|
||||
|
||||
useEffect(() => {
|
||||
const added = measurementService.EVENTS.MEASUREMENT_ADDED;
|
||||
const addedRaw = measurementService.EVENTS.RAW_MEASUREMENT_ADDED;
|
||||
@ -108,15 +106,29 @@ function PanelStudyBrowserTracking({
|
||||
};
|
||||
}, [measurementService, activeViewportIndex, sendTrackedMeasurementsEvent]);
|
||||
|
||||
const { trackedStudy, trackedSeries } = trackedMeasurements.context;
|
||||
const { trackedSeries } = trackedMeasurements.context;
|
||||
|
||||
// ~~ studyDisplayList
|
||||
useEffect(() => {
|
||||
// Fetch all studies for the patient in each primary study
|
||||
async function fetchStudiesForPatient(StudyInstanceUID) {
|
||||
const qidoStudiesForPatient =
|
||||
(await getStudiesForPatientByStudyInstanceUID(StudyInstanceUID)) || [];
|
||||
// TODO: This should be "naturalized DICOM JSON" studies
|
||||
// current study qido
|
||||
const qidoForStudyUID = await dataSource.query.studies.search({
|
||||
studyInstanceUid: StudyInstanceUID,
|
||||
});
|
||||
|
||||
let qidoStudiesForPatient = qidoForStudyUID;
|
||||
|
||||
// try to fetch the prior studies based on the patientID if the
|
||||
// server can respond.
|
||||
try {
|
||||
qidoStudiesForPatient = await getStudiesForPatientByMRN(
|
||||
qidoForStudyUID
|
||||
);
|
||||
} catch (error) {
|
||||
console.warn(error);
|
||||
}
|
||||
|
||||
const mappedStudies = _mapDataSourceStudies(qidoStudiesForPatient);
|
||||
const actuallyMappedStudies = mappedStudies.map(qidoStudy => {
|
||||
return {
|
||||
@ -125,7 +137,6 @@ function PanelStudyBrowserTracking({
|
||||
description: qidoStudy.StudyDescription,
|
||||
modalities: qidoStudy.ModalitiesInStudy,
|
||||
numInstances: qidoStudy.NumInstances,
|
||||
// displaySets: []
|
||||
};
|
||||
});
|
||||
|
||||
@ -146,11 +157,16 @@ function PanelStudyBrowserTracking({
|
||||
|
||||
StudyInstanceUIDs.forEach(sid => fetchStudiesForPatient(sid));
|
||||
// eslint-disable-next-line react-hooks/exhaustive-deps
|
||||
}, [StudyInstanceUIDs, getStudiesForPatientByStudyInstanceUID]);
|
||||
}, [StudyInstanceUIDs, getStudiesForPatientByMRN]);
|
||||
|
||||
// ~~ Initial Thumbnails
|
||||
useEffect(() => {
|
||||
const currentDisplaySets = displaySetService.activeDisplaySets;
|
||||
|
||||
if (!currentDisplaySets.length) {
|
||||
return;
|
||||
}
|
||||
|
||||
currentDisplaySets.forEach(async dSet => {
|
||||
const newImageSrcEntry = {};
|
||||
const displaySet = displaySetService.getDisplaySetByUID(
|
||||
@ -170,13 +186,16 @@ function PanelStudyBrowserTracking({
|
||||
});
|
||||
}
|
||||
});
|
||||
// eslint-disable-next-line react-hooks/exhaustive-deps
|
||||
}, [displaySetService, dataSource, getImageSrc]);
|
||||
|
||||
// ~~ displaySets
|
||||
useEffect(() => {
|
||||
// TODO: Are we sure `activeDisplaySets` will always be accurate?
|
||||
const currentDisplaySets = displaySetService.activeDisplaySets;
|
||||
|
||||
if (!currentDisplaySets.length) {
|
||||
return;
|
||||
}
|
||||
|
||||
const mappedDisplaySets = _mapDisplaySets(
|
||||
currentDisplaySets,
|
||||
thumbnailImageSrcMap,
|
||||
@ -194,9 +213,9 @@ function PanelStudyBrowserTracking({
|
||||
}, [
|
||||
displaySetService.activeDisplaySets,
|
||||
trackedSeries,
|
||||
thumbnailImageSrcMap,
|
||||
viewports,
|
||||
dataSource,
|
||||
thumbnailImageSrcMap,
|
||||
]);
|
||||
|
||||
// ~~ subscriptions --> displaySets
|
||||
@ -379,7 +398,7 @@ PanelStudyBrowserTracking.propTypes = {
|
||||
getImageIdsForDisplaySet: PropTypes.func.isRequired,
|
||||
}).isRequired,
|
||||
getImageSrc: PropTypes.func.isRequired,
|
||||
getStudiesForPatientByStudyInstanceUID: PropTypes.func.isRequired,
|
||||
getStudiesForPatientByMRN: PropTypes.func.isRequired,
|
||||
requestDisplaySetCreationForStudy: PropTypes.func.isRequired,
|
||||
};
|
||||
|
||||
|
||||
@ -6,7 +6,7 @@ function getImageSrcFromImageId(cornerstone, imageId) {
|
||||
return new Promise((resolve, reject) => {
|
||||
const canvas = document.createElement('canvas');
|
||||
cornerstone.utilities
|
||||
.loadImageToCanvas(canvas, imageId)
|
||||
.loadImageToCanvas({ canvas, imageId })
|
||||
.then(imageId => {
|
||||
resolve(canvas.toDataURL());
|
||||
})
|
||||
|
||||
@ -10,8 +10,8 @@ function _getStudyForPatientUtility(extensionManager) {
|
||||
'@ohif/extension-default.utilityModule.common'
|
||||
);
|
||||
|
||||
const { getStudiesForPatientByStudyInstanceUID } = utilityModule.exports;
|
||||
return getStudiesForPatientByStudyInstanceUID;
|
||||
const { getStudiesForPatientByMRN } = utilityModule.exports;
|
||||
return getStudiesForPatientByMRN;
|
||||
}
|
||||
|
||||
/**
|
||||
@ -28,10 +28,10 @@ function WrappedPanelStudyBrowserTracking({
|
||||
}) {
|
||||
const dataSource = extensionManager.getActiveDataSource()[0];
|
||||
|
||||
const getStudiesForPatientByStudyInstanceUID = _getStudyForPatientUtility(
|
||||
const getStudiesForPatientByMRN = _getStudyForPatientUtility(
|
||||
extensionManager
|
||||
);
|
||||
const _getStudiesForPatientByStudyInstanceUID = getStudiesForPatientByStudyInstanceUID.bind(
|
||||
const _getStudiesForPatientByMRN = getStudiesForPatientByMRN.bind(
|
||||
null,
|
||||
dataSource
|
||||
);
|
||||
@ -48,9 +48,7 @@ function WrappedPanelStudyBrowserTracking({
|
||||
servicesManager={servicesManager}
|
||||
dataSource={dataSource}
|
||||
getImageSrc={_getImageSrcFromImageId}
|
||||
getStudiesForPatientByStudyInstanceUID={
|
||||
_getStudiesForPatientByStudyInstanceUID
|
||||
}
|
||||
getStudiesForPatientByMRN={_getStudiesForPatientByMRN}
|
||||
requestDisplaySetCreationForStudy={_requestDisplaySetCreationForStudy}
|
||||
/>
|
||||
);
|
||||
|
||||
@ -1,29 +0,0 @@
|
||||
async function getStudiesForPatientByStudyInstanceUID(
|
||||
dataSource,
|
||||
StudyInstanceUID
|
||||
) {
|
||||
if (StudyInstanceUID === undefined) {
|
||||
return;
|
||||
}
|
||||
// TODO: The `DicomMetadataStore` should short-circuit both of these requests
|
||||
// Data _could_ be here from route query, or if using JSON data source
|
||||
// We could also force this to "await" these values being available in the DICOMStore?
|
||||
// Kind of like promise fulfillment in @cornerstonejs/dicom-image-loader when there are multiple
|
||||
// outgoing requests for the same data
|
||||
const getStudyResult = await dataSource.query.studies.search({
|
||||
studyInstanceUid: StudyInstanceUID,
|
||||
});
|
||||
|
||||
// TODO: To Erik's point, the data source likely shouldn't deviate from
|
||||
// Naturalized DICOM JSON when returning. It makes things like this awkward (mrn)
|
||||
if (getStudyResult && getStudyResult.length && getStudyResult[0].mrn) {
|
||||
return dataSource.query.studies.search({
|
||||
patientId: getStudyResult[0].mrn,
|
||||
});
|
||||
}
|
||||
console.log('No mrn found for', getStudyResult);
|
||||
// The original study we KNOW belongs to the same set, so just return it
|
||||
return getStudyResult;
|
||||
}
|
||||
|
||||
export default getStudiesForPatientByStudyInstanceUID;
|
||||
@ -32,7 +32,7 @@
|
||||
},
|
||||
"peerDependencies": {
|
||||
"cornerstone-math": "0.1.9",
|
||||
"@cornerstonejs/dicom-image-loader": "^0.4.0",
|
||||
"@cornerstonejs/dicom-image-loader": "^0.6.4",
|
||||
"@cornerstonejs/codec-charls": "^1.2.3",
|
||||
"@cornerstonejs/codec-libjpeg-turbo-8bit": "^1.2.2",
|
||||
"@cornerstonejs/codec-openjpeg": "^1.2.2",
|
||||
|
||||
@ -481,6 +481,9 @@ class MetadataProvider {
|
||||
imageURI = imageIdToURI(imageId);
|
||||
}
|
||||
|
||||
// remove &frame=number from imageId
|
||||
imageURI = imageURI.split('&frame=')[0];
|
||||
|
||||
const uids = this.imageURIToUIDs.get(imageURI);
|
||||
let frameNumber = this.getFrameInformationFromURL(imageId) || '1';
|
||||
|
||||
|
||||
@ -63,7 +63,7 @@ export default class CustomizationService extends PubSubService {
|
||||
|
||||
modeCustomizations: Record<string, Customization> = {};
|
||||
globalCustomizations: Record<string, Customization> = {};
|
||||
configuration: CustomizationConfiguration;
|
||||
configuration: any;
|
||||
|
||||
constructor({ configuration, commandsManager }) {
|
||||
super(EVENTS);
|
||||
|
||||
67
platform/docs/docs/deployment/authorization.md
Normal file
67
platform/docs/docs/deployment/authorization.md
Normal file
@ -0,0 +1,67 @@
|
||||
---
|
||||
sidebar_position: 8
|
||||
sidebar_label: Authorization
|
||||
---
|
||||
|
||||
# Authorization
|
||||
The OHIF Viewer can be configured to work with authorization servers that support one or more of the OpenID-Connect authorization flows. The Viewer finds it's OpenID-Connect settings on the oidc configuration key. You can set these values in your configuration files. For instance you can take a look at our
|
||||
`google.js` configuration file.
|
||||
|
||||
|
||||
```js
|
||||
oidc: [
|
||||
{
|
||||
// ~ REQUIRED
|
||||
// Authorization Server URL
|
||||
authority: 'https://accounts.google.com',
|
||||
client_id:
|
||||
'723928408739-k9k9r3i44j32rhu69vlnibipmmk9i57p.apps.googleusercontent.com',
|
||||
redirect_uri: '/callback',
|
||||
response_type: 'id_token token',
|
||||
scope:
|
||||
'email profile openid https://www.googleapis.com/auth/cloudplatformprojects.readonly https://www.googleapis.com/auth/cloud-healthcare', // email profile openid
|
||||
// ~ OPTIONAL
|
||||
post_logout_redirect_uri: '/logout-redirect.html',
|
||||
revoke_uri: 'https://accounts.google.com/o/oauth2/revoke?token=',
|
||||
automaticSilentRenew: true,
|
||||
revokeAccessTokenOnSignout: true,
|
||||
},
|
||||
],
|
||||
```
|
||||
|
||||
You need to provide the following information:
|
||||
- authority: The URL of the authorization server.
|
||||
- client_id: The client id of your application (provided by the authorization server).
|
||||
- redirect_uri: The callback URL of your application.
|
||||
- response_type: The response type of the authorization flow (e.g. id_token token, [learn more about different flows](https://darutk.medium.com/diagrams-of-all-the-openid-connect-flows-6968e3990660)).
|
||||
- scope: The scopes that your application needs to access
|
||||
- post_logout_redirect_uri: The URL that the user will be redirected to after logout.
|
||||
- revoke_uri: The URL that the user will be redirected to after logout.
|
||||
- automaticSilentRenew: If true, the user will be automatically logged in after the token expires.
|
||||
- revokeAccessTokenOnSignout: If true, the access token will be revoked on logout.
|
||||
|
||||
|
||||
|
||||
## How it works
|
||||
The Viewer uses the `userAuthenticationService` to set the OpenID-Connect settings. The `userAuthenticationService` is a singleton service that is responsible for authentication and authorization. It is initialized by the app and you can grab it
|
||||
from the `servicesManager`
|
||||
|
||||
```js
|
||||
const userAuthenticationService = servicesManager.services.userAuthenticationService;
|
||||
```
|
||||
|
||||
Then the userAuthenticationService will inject the token as Authorization header in the requests that are sent to the server (both metadata
|
||||
and pixelData).
|
||||
|
||||
|
||||
## Token based authentication
|
||||
Sometimes (although not recommended), some servers like to send the token
|
||||
in the query string. In this case, the viewer will automatically grab the token from the query string
|
||||
and add it to the userAuthenticationService and remove it from the query string (to prevent it from being logged in the console
|
||||
in future requests).
|
||||
|
||||
and example would be
|
||||
|
||||
```js
|
||||
http://localhost:3000/viewer?StudyInstanceUIDs=1.2.3.4.5.6.6.7&token=e123125jsdfahsdf
|
||||
```
|
||||
@ -9,6 +9,23 @@ Throughout the development of the OHIF Viewer, we have participated in various
|
||||
conferences and "hackathons". In this page, we will provide the presentations
|
||||
and other resources that we have provided to the community in the past:
|
||||
|
||||
## 2023
|
||||
### SIIM 2023 Tech Tools Webinar | April 12th, 2023
|
||||
|
||||
Free, Open Source Tools for Research: MONAI and OHIF Viewer
|
||||
[[Slides](https://docs.google.com/presentation/d/1afJ5Y9Tzukgn7eAbaO1oiCtN7XvIimFdmZP-HcOUofA/edit?usp=sharing)][[Video](https://www.youtube.com/watch?v=lo8J5w5jUJI)]
|
||||
|
||||
|
||||
### [NA-MIC Project Week 38th 2023 - Remote]
|
||||
|
||||
We participated in the 38th Project Week with three projects around OHIF. [[Website](https://projectweek.na-mic.org/PW38_2023_GranCanaria/)]
|
||||
|
||||
- PolySeg representations for OHIF Viewer ([link](https://projectweek.na-mic.org/PW38_2023_GranCanaria/Projects/OHIF_PolySeg/))
|
||||
- Cross study sychronizer for OHIF Crosshair ([link](https://projectweek.na-mic.org/PW38_2023_GranCanaria/Projects/OHIF_SyncCrosshair/))
|
||||
- DATSCAN Viewer implementation in OHIF ([link](https://projectweek.na-mic.org/PW38_2023_GranCanaria/Projects/OHIF_DATSCAN/))
|
||||
|
||||
|
||||
|
||||
## 2022
|
||||
|
||||
### OHIF Demo to Interns
|
||||
|
||||
@ -68,7 +68,7 @@
|
||||
"config-point": "^0.4.8",
|
||||
"core-js": "^3.16.1",
|
||||
"cornerstone-math": "^0.1.9",
|
||||
"@cornerstonejs/dicom-image-loader": "^0.4.0",
|
||||
"@cornerstonejs/dicom-image-loader": "^0.6.4",
|
||||
"@cornerstonejs/codec-charls": "^1.2.3",
|
||||
"@cornerstonejs/codec-libjpeg-turbo-8bit": "^1.2.2",
|
||||
"@cornerstonejs/codec-openjpeg": "^1.2.2",
|
||||
|
||||
@ -99,7 +99,6 @@ export default function ModeRoute({
|
||||
const params = useParams();
|
||||
const searchParams = useSearchParams();
|
||||
|
||||
const runTimeHangingProtocolId = searchParams.get('hangingprotocolid');
|
||||
const [studyInstanceUIDs, setStudyInstanceUIDs] = useState();
|
||||
|
||||
const [refresh, setRefresh] = useState(false);
|
||||
@ -123,6 +122,7 @@ export default function ModeRoute({
|
||||
const {
|
||||
displaySetService,
|
||||
hangingProtocolService,
|
||||
userAuthenticationService,
|
||||
} = (servicesManager as ServicesManager).services;
|
||||
|
||||
const {
|
||||
@ -131,6 +131,34 @@ export default function ModeRoute({
|
||||
hotkeys: hotkeyObj,
|
||||
hangingProtocol,
|
||||
} = mode;
|
||||
|
||||
const runTimeHangingProtocolId = searchParams.get('hangingprotocolid');
|
||||
const token = searchParams.get('token');
|
||||
|
||||
if (token) {
|
||||
// if a token is passed in, set the userAuthenticationService to use it
|
||||
// for the Authorization header for all requests
|
||||
userAuthenticationService.setServiceImplementation({
|
||||
getAuthorizationHeader: () => ({
|
||||
Authorization: 'Bearer ' + token,
|
||||
}),
|
||||
});
|
||||
|
||||
// Create a URL object with the current location
|
||||
const urlObj = new URL(
|
||||
window.location.origin + location.pathname + location.search
|
||||
);
|
||||
|
||||
// Remove the token from the URL object
|
||||
urlObj.searchParams.delete('token');
|
||||
const cleanUrl = urlObj.toString();
|
||||
|
||||
// Update the browser's history without the token
|
||||
if (window.history && window.history.replaceState) {
|
||||
window.history.replaceState(null, '', cleanUrl);
|
||||
}
|
||||
}
|
||||
|
||||
// Preserve the old array interface for hotkeys
|
||||
const hotkeys = Array.isArray(hotkeyObj) ? hotkeyObj : hotkeyObj?.hotkeys;
|
||||
const hotkeyName = hotkeyObj?.name || 'hotkey-definitions-v2';
|
||||
|
||||
109
yarn.lock
109
yarn.lock
@ -223,15 +223,6 @@
|
||||
json5 "^2.2.2"
|
||||
semver "^6.3.0"
|
||||
|
||||
"@babel/eslint-parser@^7.19.1":
|
||||
version "7.21.3"
|
||||
resolved "https://registry.npmjs.org/@babel/eslint-parser/-/eslint-parser-7.21.3.tgz#d79e822050f2de65d7f368a076846e7184234af7"
|
||||
integrity sha512-kfhmPimwo6k4P8zxNs8+T7yR44q1LdpsZdE1NkCsVlfiuTPRfnGgjaF8Qgug9q9Pou17u6wneYF0lDCZJATMFg==
|
||||
dependencies:
|
||||
"@nicolo-ribaudo/eslint-scope-5-internals" "5.1.1-v1"
|
||||
eslint-visitor-keys "^2.1.0"
|
||||
semver "^6.3.0"
|
||||
|
||||
"@babel/generator@7.0.0-beta.44":
|
||||
version "7.0.0-beta.44"
|
||||
resolved "https://registry.npmjs.org/@babel/generator/-/generator-7.0.0-beta.44.tgz#c7e67b9b5284afcf69b309b50d7d37f3e5033d42"
|
||||
@ -1478,54 +1469,43 @@
|
||||
resolved "https://registry.npmjs.org/@cornerstonejs/codec-openjph/-/codec-openjph-2.4.2.tgz#e96721d56f6ec96f7f95c16321d88cc8467d8d81"
|
||||
integrity sha512-lgdvBvvNezleY+4pIe2ceUsJzlZe/0PipdeubQ3vZZOz3xxtHHMR1XFCl4fgd8gosR8COHuD7h6q+MwgrwBsng==
|
||||
|
||||
"@cornerstonejs/core@^0.44.0":
|
||||
version "0.44.0"
|
||||
resolved "https://registry.npmjs.org/@cornerstonejs/core/-/core-0.44.0.tgz#f1a9af5407b25510e91e3e17b55dd9f3c61c557b"
|
||||
integrity sha512-EZURQAuILsmiUdp5nusUpL6pJjteVgY7DqrqkFSqeeSlDjt2j+0h+kFvvbpRAhjyWz/1OjK9vtvbRFCpwhnzJw==
|
||||
dependencies:
|
||||
detect-gpu "^4.0.45"
|
||||
lodash.clonedeep "4.5.0"
|
||||
|
||||
"@cornerstonejs/core@^0.44.2":
|
||||
version "0.44.2"
|
||||
resolved "https://registry.npmjs.org/@cornerstonejs/core/-/core-0.44.2.tgz#13febc0455c833b029fac4a00a2e98f67ef50609"
|
||||
integrity sha512-McwG04aFbxhA8LAAgZuh4ttFFW35CMvHwNrfYnQqaExCb62w1lzQBIHDopX05aGe9VAmmIRhaAuhaxxnH8ZsfA==
|
||||
"@cornerstonejs/core@^0.46.2":
|
||||
version "0.46.2"
|
||||
resolved "https://registry.npmjs.org/@cornerstonejs/core/-/core-0.46.2.tgz#89ba0d27f491aab8b0a22d15ce5ed601ee23d2ec"
|
||||
integrity sha512-HHActbdv3np/QXmQPl+DOqVMXPeOXbkqDov1SagF1om6Me4V7O8N2HbM4CgKCdf2VrEId6h0BL3+MG3Cxn7LPQ==
|
||||
dependencies:
|
||||
"@kitware/vtk.js" "27.3.1"
|
||||
detect-gpu "^5.0.22"
|
||||
gl-matrix "^3.4.3"
|
||||
lodash.clonedeep "4.5.0"
|
||||
|
||||
"@cornerstonejs/dicom-image-loader@^0.4.0":
|
||||
version "0.4.0"
|
||||
resolved "https://registry.npmjs.org/@cornerstonejs/dicom-image-loader/-/dicom-image-loader-0.4.0.tgz#c7f5c5659a10a6f4f5e96367ab6d27784daeb424"
|
||||
integrity sha512-ORnF/4qAbTninkesz7ADQu832PW+/xcbUhxSPU1ZPukjr9cglynsDzKjsEYJlY10+rWzbIQ+JEgefrXZgVoT1g==
|
||||
"@cornerstonejs/dicom-image-loader@^0.6.4":
|
||||
version "0.6.4"
|
||||
resolved "https://registry.npmjs.org/@cornerstonejs/dicom-image-loader/-/dicom-image-loader-0.6.4.tgz#8020402b11dd78df52957345ca57ed8c05b2999b"
|
||||
integrity sha512-+y9NklTFYlq61frxKcJ2u+0h9zfKKiv20N28N5qBr3Ie6CFcNrY51ETkujNnNKKRUBvxXDidjVdY+j+MSPPJKQ==
|
||||
dependencies:
|
||||
"@babel/eslint-parser" "^7.19.1"
|
||||
"@cornerstonejs/codec-charls" "^1.2.3"
|
||||
"@cornerstonejs/codec-libjpeg-turbo-8bit" "^1.2.2"
|
||||
"@cornerstonejs/codec-openjpeg" "^1.2.2"
|
||||
"@cornerstonejs/codec-openjph" "^2.4.2"
|
||||
"@cornerstonejs/core" "^0.44.0"
|
||||
coverage-istanbul-loader "^3.0.5"
|
||||
date-format "^4.0.14"
|
||||
"@cornerstonejs/core" "^0.46.2"
|
||||
dicom-parser "^1.8.9"
|
||||
pako "^2.0.4"
|
||||
uuid "^9.0.0"
|
||||
|
||||
"@cornerstonejs/streaming-image-volume-loader@^0.19.2":
|
||||
version "0.19.2"
|
||||
resolved "https://registry.npmjs.org/@cornerstonejs/streaming-image-volume-loader/-/streaming-image-volume-loader-0.19.2.tgz#2d83fda24d9fe7a4a1b8fda334a82bddd000fb40"
|
||||
integrity sha512-N2ws5GBsBnvdQB1gNI03WdiF71LeL5CGcdmkgAZMqFdtiiNbOlf0jW8ZmDwALY3+eL8kv2viHM3aLraXVT9Wwg==
|
||||
"@cornerstonejs/streaming-image-volume-loader@^0.20.2":
|
||||
version "0.20.2"
|
||||
resolved "https://registry.npmjs.org/@cornerstonejs/streaming-image-volume-loader/-/streaming-image-volume-loader-0.20.2.tgz#0df2ed5afd012d2851356af01eed48646d3a6c60"
|
||||
integrity sha512-2TYoJ0wpE9KDpn8adfmTq0xOb/Xg7jhEyOuBnrr3il/NFvOfMlJieJVCYM0v3hyoANfqmDcFBqqtlm346VOMdw==
|
||||
dependencies:
|
||||
"@cornerstonejs/core" "^0.44.2"
|
||||
"@cornerstonejs/core" "^0.46.2"
|
||||
|
||||
"@cornerstonejs/tools@^0.66.2":
|
||||
version "0.66.2"
|
||||
resolved "https://registry.npmjs.org/@cornerstonejs/tools/-/tools-0.66.2.tgz#58e76ea1c239bcf87a7c00ff661429804e09533a"
|
||||
integrity sha512-ykSqhjJUIjgFDi9Ua0HwDTbXip8IMeeyM/3oMUlIINKURwvhipzJY6eWrmgwFzIlsXID4oLFPZq3V/V9lSqkaQ==
|
||||
"@cornerstonejs/tools@^0.67.2":
|
||||
version "0.67.2"
|
||||
resolved "https://registry.npmjs.org/@cornerstonejs/tools/-/tools-0.67.2.tgz#7b7c6aac4ec7eaa84a438198837e657328e3c8a2"
|
||||
integrity sha512-nOg2byAVrdMj3DqLYVT7qbrl2Sz6V82xtfFYJ4oQeGul/u/1AvHj4SSZs7MTV63Li3KP2ax/ZghCjral+exaVg==
|
||||
dependencies:
|
||||
"@cornerstonejs/core" "^0.44.2"
|
||||
"@cornerstonejs/core" "^0.46.2"
|
||||
lodash.clonedeep "4.5.0"
|
||||
lodash.get "^4.4.2"
|
||||
|
||||
@ -2721,17 +2701,6 @@
|
||||
"@jridgewell/resolve-uri" "3.1.0"
|
||||
"@jridgewell/sourcemap-codec" "1.4.14"
|
||||
|
||||
"@jsdevtools/coverage-istanbul-loader@3.0.5":
|
||||
version "3.0.5"
|
||||
resolved "https://registry.npmjs.org/@jsdevtools/coverage-istanbul-loader/-/coverage-istanbul-loader-3.0.5.tgz#2a4bc65d0271df8d4435982db4af35d81754ee26"
|
||||
integrity sha512-EUCPEkaRPvmHjWAAZkWMT7JDzpw7FKB00WTISaiXsbNOd5hCHg77XLA8sLYLFDo1zepYLo2w7GstN8YBqRXZfA==
|
||||
dependencies:
|
||||
convert-source-map "^1.7.0"
|
||||
istanbul-lib-instrument "^4.0.3"
|
||||
loader-utils "^2.0.0"
|
||||
merge-source-map "^1.1.0"
|
||||
schema-utils "^2.7.0"
|
||||
|
||||
"@juggle/resize-observer@^3.3.1":
|
||||
version "3.4.0"
|
||||
resolved "https://registry.npmjs.org/@juggle/resize-observer/-/resize-observer-3.4.0.tgz#08d6c5e20cf7e4cc02fd181c4b0c225cd31dbb60"
|
||||
@ -2955,13 +2924,6 @@
|
||||
pump "^3.0.0"
|
||||
tar-fs "^2.1.1"
|
||||
|
||||
"@nicolo-ribaudo/eslint-scope-5-internals@5.1.1-v1":
|
||||
version "5.1.1-v1"
|
||||
resolved "https://registry.npmjs.org/@nicolo-ribaudo/eslint-scope-5-internals/-/eslint-scope-5-internals-5.1.1-v1.tgz#dbf733a965ca47b1973177dc0bb6c889edcfb129"
|
||||
integrity sha512-54/JRvkLIzzDWshCWfuhadfrfZVPiElY8Fcgmg1HroEly/EDSszzhBAsarCux+D/kOslTRquNzuyGSmUSTTHGg==
|
||||
dependencies:
|
||||
eslint-scope "5.1.1"
|
||||
|
||||
"@nodelib/fs.scandir@2.1.5":
|
||||
version "2.1.5"
|
||||
resolved "https://registry.npmjs.org/@nodelib/fs.scandir/-/fs.scandir-2.1.5.tgz#7619c2eb21b25483f6d167548b4cfd5a7488c3d5"
|
||||
@ -7805,13 +7767,6 @@ cosmiconfig@^8.1.3:
|
||||
parse-json "^5.0.0"
|
||||
path-type "^4.0.0"
|
||||
|
||||
coverage-istanbul-loader@^3.0.5:
|
||||
version "3.0.5"
|
||||
resolved "https://registry.npmjs.org/coverage-istanbul-loader/-/coverage-istanbul-loader-3.0.5.tgz#bf942efc0f4e3ac27565203c17dca5008eae6637"
|
||||
integrity sha512-xsw2phF0VNqUPk47V/vHXkdcTyl0tkMSmaZfLrTOhoPhPMXFelNju7utl5s7I93KXzipqDEK0YwofQSSflPz8A==
|
||||
dependencies:
|
||||
"@jsdevtools/coverage-istanbul-loader" "3.0.5"
|
||||
|
||||
cross-env@^5.2.0:
|
||||
version "5.2.1"
|
||||
resolved "https://registry.npmjs.org/cross-env/-/cross-env-5.2.1.tgz#b2c76c1ca7add66dc874d11798466094f551b34d"
|
||||
@ -8263,11 +8218,6 @@ date-fns@^1.27.2:
|
||||
resolved "https://registry.npmjs.org/date-fns/-/date-fns-1.30.1.tgz#2e71bf0b119153dbb4cc4e88d9ea5acfb50dc05c"
|
||||
integrity sha512-hBSVCvSmWC+QypYObzwGOd9wqdDpOt+0wl0KbU+R+uuZBS1jN8VsD1ss3irQDknRj5NvxiTF6oj/nDRnN/UQNw==
|
||||
|
||||
date-format@^4.0.14:
|
||||
version "4.0.14"
|
||||
resolved "https://registry.npmjs.org/date-format/-/date-format-4.0.14.tgz#7a8e584434fb169a521c8b7aa481f355810d9400"
|
||||
integrity sha512-39BOQLs9ZjKh0/patS9nrT8wc3ioX3/eA/zgbKNopnF2wCqJEoxywwwElATYvRsXdnOxA/OQeQoFZ3rFjVajhg==
|
||||
|
||||
dateformat@^3.0.0:
|
||||
version "3.0.3"
|
||||
resolved "https://registry.npmjs.org/dateformat/-/dateformat-3.0.3.tgz#a6e37499a4d9a9cf85ef5872044d62901c9889ae"
|
||||
@ -8569,7 +8519,7 @@ detab@2.0.4:
|
||||
dependencies:
|
||||
repeat-string "^1.5.4"
|
||||
|
||||
detect-gpu@^4.0.16, detect-gpu@^4.0.45:
|
||||
detect-gpu@^4.0.16:
|
||||
version "4.0.50"
|
||||
resolved "https://registry.npmjs.org/detect-gpu/-/detect-gpu-4.0.50.tgz#ba9df7e6b8416b1160303811015102bbad283aa0"
|
||||
integrity sha512-T67HE5+ONONN8rPXCBJPupyCg2QT8+l2NUUMuPxAppsMJBDPG/Jg0URLs6GyDzLm2niUE+oncIHSuy3VinoPeQ==
|
||||
@ -9543,7 +9493,7 @@ eslint-visitor-keys@^1.0.0, eslint-visitor-keys@^1.1.0, eslint-visitor-keys@^1.3
|
||||
resolved "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-1.3.0.tgz#30ebd1ef7c2fdff01c3a4f151044af25fab0523e"
|
||||
integrity sha512-6J72N8UNa462wa/KFODt/PJ3IU60SDpC3QXC1Hjc1BXXpfL2C9R5+AU7jhe0F6GREqVMh4Juu+NY7xn+6dipUQ==
|
||||
|
||||
eslint-visitor-keys@^2.0.0, eslint-visitor-keys@^2.1.0:
|
||||
eslint-visitor-keys@^2.0.0:
|
||||
version "2.1.0"
|
||||
resolved "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-2.1.0.tgz#f65328259305927392c938ed44eb0a5c9b2bd303"
|
||||
integrity sha512-0rSmRBzXgDzIsD6mGdJgevzgezI534Cer5L/vyMX0kHzT/jiB43jRhd9YUlMGYLQy2zprNmoT8qasCGtY+QaKw==
|
||||
@ -12369,16 +12319,6 @@ istanbul-lib-coverage@^3.0.0, istanbul-lib-coverage@^3.2.0:
|
||||
resolved "https://registry.npmjs.org/istanbul-lib-coverage/-/istanbul-lib-coverage-3.2.0.tgz#189e7909d0a39fa5a3dfad5b03f71947770191d3"
|
||||
integrity sha512-eOeJ5BHCmHYvQK7xt9GkdHuzuCGS1Y6g9Gvnx3Ym33fz/HpLRYxiS0wHNr+m/MBC8B647Xt608vCDEvhl9c6Mw==
|
||||
|
||||
istanbul-lib-instrument@^4.0.3:
|
||||
version "4.0.3"
|
||||
resolved "https://registry.npmjs.org/istanbul-lib-instrument/-/istanbul-lib-instrument-4.0.3.tgz#873c6fff897450118222774696a3f28902d77c1d"
|
||||
integrity sha512-BXgQl9kf4WTCPCCpmFGoJkz/+uhvm7h7PFKUYxh7qarQd3ER33vHG//qaE8eN25l07YqZPpHXU9I09l/RD5aGQ==
|
||||
dependencies:
|
||||
"@babel/core" "^7.7.5"
|
||||
"@istanbuljs/schema" "^0.1.2"
|
||||
istanbul-lib-coverage "^3.0.0"
|
||||
semver "^6.3.0"
|
||||
|
||||
istanbul-lib-instrument@^5.0.4, istanbul-lib-instrument@^5.1.0:
|
||||
version "5.2.1"
|
||||
resolved "https://registry.npmjs.org/istanbul-lib-instrument/-/istanbul-lib-instrument-5.2.1.tgz#d10c8885c2125574e1c231cacadf955675e1ce3d"
|
||||
@ -14070,13 +14010,6 @@ merge-descriptors@1.0.1:
|
||||
resolved "https://registry.npmjs.org/merge-descriptors/-/merge-descriptors-1.0.1.tgz#b00aaa556dd8b44568150ec9d1b953f3f90cbb61"
|
||||
integrity sha512-cCi6g3/Zr1iqQi6ySbseM1Xvooa98N0w31jzUYrXPX2xqObmFGHJ0tQ5u74H3mVh7wLouTseZyYIq39g8cNp1w==
|
||||
|
||||
merge-source-map@^1.1.0:
|
||||
version "1.1.0"
|
||||
resolved "https://registry.npmjs.org/merge-source-map/-/merge-source-map-1.1.0.tgz#2fdde7e6020939f70906a68f2d7ae685e4c8c646"
|
||||
integrity sha512-Qkcp7P2ygktpMPh2mCQZaf3jhN6D3Z/qVZHSdWvQ+2Ef5HgRAPBO57A77+ENm0CPx2+1Ce/MYKi3ymqdfuqibw==
|
||||
dependencies:
|
||||
source-map "^0.6.1"
|
||||
|
||||
merge-stream@^2.0.0:
|
||||
version "2.0.0"
|
||||
resolved "https://registry.npmjs.org/merge-stream/-/merge-stream-2.0.0.tgz#52823629a14dd00c9770fb6ad47dc6310f2c1f60"
|
||||
|
||||
Loading…
Reference in New Issue
Block a user