Compare commits
9
Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
78344c2c66 | ||
|
|
b451ce4407 | ||
|
|
21b586b08f | ||
|
|
3bbeb1c521 | ||
|
|
7668b69f20 | ||
|
|
3a12138134 | ||
|
|
97786b808c | ||
|
|
cd1baa1b36 | ||
|
|
3ae3bee452 |
No files matched your search
@@ -3,6 +3,17 @@
|
||||
All notable changes to this project will be documented in this file.
|
||||
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
|
||||
|
||||
## [0.52.17](https://github.com/OHIF/Viewers/compare/@ohif/extension-vtk@0.52.16...@ohif/extension-vtk@0.52.17) (2019-10-25)
|
||||
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
* 🐛 Fix crosshairs location when using MIP ([#1080](https://github.com/OHIF/Viewers/issues/1080)) ([b451ce4](https://github.com/OHIF/Viewers/commit/b451ce440796f13b0891739d2130e8ee71993d3d))
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
## [0.52.16](https://github.com/OHIF/Viewers/compare/@ohif/extension-vtk@0.52.15...@ohif/extension-vtk@0.52.16) (2019-10-23)
|
||||
|
||||
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@ohif/extension-vtk",
|
||||
"version": "0.52.16",
|
||||
"version": "0.52.17",
|
||||
"description": "OHIF extension for VTK.js",
|
||||
"author": "OHIF",
|
||||
"license": "MIT",
|
||||
@@ -49,10 +49,10 @@
|
||||
"dependencies": {
|
||||
"@babel/runtime": "^7.5.5",
|
||||
"lodash.throttle": "^4.1.1",
|
||||
"react-vtkjs-viewport": "^0.3.5"
|
||||
"react-vtkjs-viewport": "^0.3.6"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@ohif/core": "^1.4.0",
|
||||
"@ohif/core": "^1.5.0",
|
||||
"@ohif/ui": "^0.56.0",
|
||||
"cornerstone-tools": "^4.0.9",
|
||||
"cornerstone-wado-image-loader": "^3.0.0",
|
||||
|
||||
@@ -3,6 +3,17 @@
|
||||
All notable changes to this project will be documented in this file.
|
||||
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
|
||||
|
||||
# [1.5.0](https://github.com/OHIF/Viewers/compare/@ohif/core@1.4.0...@ohif/core@1.5.0) (2019-10-25)
|
||||
|
||||
|
||||
### Features
|
||||
|
||||
* 🎸 Allow routes to load Google Cloud DICOM Stores in the Study List ([#1069](https://github.com/OHIF/Viewers/issues/1069)) ([21b586b](https://github.com/OHIF/Viewers/commit/21b586b08f3dde6613859712a9e0577dece564db))
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
# [1.4.0](https://github.com/OHIF/Viewers/compare/@ohif/core@1.3.2...@ohif/core@1.4.0) (2019-10-15)
|
||||
|
||||
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@ohif/core",
|
||||
"version": "1.4.0",
|
||||
"version": "1.5.0",
|
||||
"description": "Generic business logic for web-based medical imaging applications",
|
||||
"author": "OHIF Core Team",
|
||||
"license": "MIT",
|
||||
|
||||
@@ -6,7 +6,7 @@ const PARAM_PATTERN_IDENTIFIER = ':';
|
||||
function toLowerCaseFirstLetter(word) {
|
||||
return word[0].toLowerCase() + word.slice(1);
|
||||
}
|
||||
const getFilters = (location = {}) => {
|
||||
const getQueryFilters = (location = {}) => {
|
||||
const { search } = location;
|
||||
|
||||
if (!search) {
|
||||
@@ -55,13 +55,19 @@ const replaceParam = (path = '', paramKey, paramValue) => {
|
||||
return path;
|
||||
};
|
||||
|
||||
const isValidPath = path => {
|
||||
const paramPatternPiece = `/${PARAM_PATTERN_IDENTIFIER}`;
|
||||
return path.indexOf(paramPatternPiece) < 0;
|
||||
};
|
||||
|
||||
const queryString = {
|
||||
getQueryFilters: getFilters,
|
||||
getQueryFilters,
|
||||
};
|
||||
|
||||
const paramString = {
|
||||
parseParam: parseParam,
|
||||
replaceParam: replaceParam,
|
||||
isValidPath,
|
||||
parseParam,
|
||||
replaceParam,
|
||||
};
|
||||
|
||||
export { parse, queryString, paramString };
|
||||
@@ -3,6 +3,21 @@
|
||||
All notable changes to this project will be documented in this file.
|
||||
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
|
||||
|
||||
# [1.12.0](https://github.com/OHIF/Viewers/compare/@ohif/viewer@1.11.5...@ohif/viewer@1.12.0) (2019-10-25)
|
||||
|
||||
|
||||
### Features
|
||||
|
||||
* 🎸 Allow routes to load Google Cloud DICOM Stores in the Study List ([#1069](https://github.com/OHIF/Viewers/issues/1069)) ([21b586b](https://github.com/OHIF/Viewers/commit/21b586b08f3dde6613859712a9e0577dece564db))
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
## [1.11.5](https://github.com/OHIF/Viewers/compare/@ohif/viewer@1.11.4...@ohif/viewer@1.11.5) (2019-10-24)
|
||||
|
||||
**Note:** Version bump only for package @ohif/viewer
|
||||
|
||||
## [1.11.4](https://github.com/OHIF/Viewers/compare/@ohif/viewer@1.11.3...@ohif/viewer@1.11.4) (2019-10-23)
|
||||
|
||||
|
||||
@@ -10,10 +25,6 @@ See [Conventional Commits](https://conventionalcommits.org) for commit guideline
|
||||
|
||||
* Revert "Revert "fix: MPR initialization"" ([#1065](https://github.com/OHIF/Viewers/issues/1065)) ([c680720](https://github.com/OHIF/Viewers/commit/c680720ce5ead58fdb399e3a356edac18093f5c0)), closes [#1062](https://github.com/OHIF/Viewers/issues/1062) [#1064](https://github.com/OHIF/Viewers/issues/1064)
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
## [1.11.3](https://github.com/OHIF/Viewers/compare/@ohif/viewer@1.11.2...@ohif/viewer@1.11.3) (2019-10-23)
|
||||
|
||||
|
||||
|
||||
@@ -5,7 +5,7 @@ describe('OHIFStandaloneViewer', () => {
|
||||
|
||||
it('loads route with at least 2 rows', () => {
|
||||
cy.screenshot();
|
||||
cy.percySnapshot();
|
||||
cy.percyCanvasSnapshot('Study List');
|
||||
|
||||
cy.get('#studyListData tr')
|
||||
.its('length')
|
||||
|
||||
@@ -12,7 +12,7 @@ describe('OHIF Study Viewer Page', () => {
|
||||
|
||||
it('checks if series thumbnails are being displayed', () => {
|
||||
cy.screenshot();
|
||||
cy.percySnapshot();
|
||||
cy.percyCanvasSnapshot('Series Thumbnails');
|
||||
|
||||
cy.get('[data-cy="thumbnail-list"]')
|
||||
.its('length')
|
||||
|
||||
@@ -22,6 +22,6 @@ describe('OHIF Microscopy Extension', () => {
|
||||
|
||||
cy.wait(3000); //Waiting for image to render before taking the snapshot
|
||||
cy.screenshot();
|
||||
cy.percySnapshot();
|
||||
cy.percyCanvasSnapshot('Microscopy Extension');
|
||||
});
|
||||
});
|
||||
@@ -21,6 +21,6 @@ describe('OHIF PDF Extension', () => {
|
||||
.should('be.eq', 1);
|
||||
|
||||
cy.screenshot();
|
||||
cy.percySnapshot();
|
||||
cy.percyCanvasSnapshot('PDF Extension');
|
||||
});
|
||||
});
|
||||
@@ -29,7 +29,7 @@ describe('OHIF VTK Extension', () => {
|
||||
|
||||
it('checks if VTK buttons are displayed on the toolbar', () => {
|
||||
cy.screenshot();
|
||||
cy.percySnapshot();
|
||||
cy.percyCanvasSnapshot('VTK Extension');
|
||||
|
||||
cy.get('@crosshairsBtn')
|
||||
.should('be.visible')
|
||||
|
||||
@@ -306,3 +306,34 @@ Cypress.Commands.add('isInViewport', element => {
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
/**
|
||||
* Percy.io Canvas screenshot workaround
|
||||
*
|
||||
*/
|
||||
Cypress.Commands.add('percyCanvasSnapshot', (name, options = {}) => {
|
||||
function convertCanvas(documentClone) {
|
||||
documentClone
|
||||
.querySelectorAll('canvas')
|
||||
.forEach(selector => canvasToImage(selector));
|
||||
|
||||
return documentClone;
|
||||
}
|
||||
|
||||
function canvasToImage(selectorOrEl) {
|
||||
let canvas =
|
||||
typeof selectorOrEl === 'object'
|
||||
? selectorOrEl
|
||||
: document.querySelector(selectorOrEl);
|
||||
let image = document.createElement('img');
|
||||
let canvasImageBase64 = canvas.toDataURL();
|
||||
|
||||
image.src = canvasImageBase64;
|
||||
image.style = 'max-width: 100%';
|
||||
canvas.setAttribute('data-percy-modified', true);
|
||||
canvas.parentElement.appendChild(image);
|
||||
canvas.style = 'display: none';
|
||||
}
|
||||
|
||||
cy.percySnapshot(name, { ...options, domTransformation: convertCanvas });
|
||||
});
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@ohif/viewer",
|
||||
"version": "1.11.4",
|
||||
"version": "1.12.0",
|
||||
"description": "OHIF Viewer",
|
||||
"author": "OHIF Contributors",
|
||||
"license": "MIT",
|
||||
@@ -45,12 +45,12 @@
|
||||
},
|
||||
"dependencies": {
|
||||
"@babel/runtime": "^7.5.5",
|
||||
"@ohif/core": "^1.4.0",
|
||||
"@ohif/core": "^1.5.0",
|
||||
"@ohif/extension-cornerstone": "^2.0.0",
|
||||
"@ohif/extension-dicom-html": "^1.0.0",
|
||||
"@ohif/extension-dicom-microscopy": "^0.50.6",
|
||||
"@ohif/extension-dicom-pdf": "^1.0.0",
|
||||
"@ohif/extension-vtk": "^0.52.16",
|
||||
"@ohif/extension-vtk": "^0.52.17",
|
||||
"@ohif/i18n": "^0.51.0",
|
||||
"@ohif/ui": "^0.56.0",
|
||||
"@tanem/react-nprogress": "^1.1.25",
|
||||
|
||||
@@ -0,0 +1,9 @@
|
||||
import React, { useEffect, useRef } from 'react';
|
||||
export default function usePrevious(value) {
|
||||
const ref = useRef();
|
||||
useEffect(() => {
|
||||
ref.current = value;
|
||||
}, [value]);
|
||||
|
||||
return ref.current;
|
||||
}
|
||||
@@ -1,8 +1,10 @@
|
||||
import React, { useContext } from 'react';
|
||||
import GoogleCloudApi from '../googleCloud/api/GoogleCloudApi';
|
||||
import usePrevious from './usePrevious';
|
||||
|
||||
import * as GoogleCloudUtilServers from '../googleCloud/utils/getServers';
|
||||
import { useSelector, useDispatch } from 'react-redux';
|
||||
import isEqual from 'lodash.isequal';
|
||||
|
||||
// Contexts
|
||||
import AppContext from '../context/AppContext';
|
||||
@@ -32,28 +34,68 @@ const getServers = (appConfig, project, location, dataset, dicomStore) => {
|
||||
wadoRoot: pathUrl,
|
||||
};
|
||||
servers = GoogleCloudUtilServers.getServers(data, dicomStore);
|
||||
if (!isValidServer(servers[0], appConfig)) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
return servers;
|
||||
};
|
||||
|
||||
const updateServer = (
|
||||
const isValidServer = (server, appConfig) => {
|
||||
if (appConfig.enableGoogleCloudAdapter) {
|
||||
return GoogleCloudUtilServers.isValidServer(server);
|
||||
}
|
||||
|
||||
return !!server;
|
||||
};
|
||||
|
||||
const setServers = (dispatch, servers) => {
|
||||
const action = {
|
||||
type: 'SET_SERVERS',
|
||||
servers,
|
||||
};
|
||||
dispatch(action);
|
||||
};
|
||||
|
||||
const useServerFromUrl = (
|
||||
servers = [],
|
||||
previousServers,
|
||||
activeServer,
|
||||
urlBasedServers,
|
||||
appConfig,
|
||||
dispatch,
|
||||
project,
|
||||
location,
|
||||
dataset,
|
||||
dicomStore
|
||||
) => {
|
||||
const servers = getServers(appConfig, project, location, dataset, dicomStore);
|
||||
|
||||
if (servers && servers.length) {
|
||||
const action = {
|
||||
type: 'SET_SERVERS',
|
||||
servers,
|
||||
};
|
||||
dispatch(action);
|
||||
// update state from url available only when gcloud on
|
||||
if (!appConfig.enableGoogleCloudAdapter) {
|
||||
return false;
|
||||
}
|
||||
|
||||
const serverHasChanged = previousServers !== servers && previousServers;
|
||||
|
||||
// do not update from url. use state instead.
|
||||
if (serverHasChanged) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// if no valid urlbased servers
|
||||
if (!urlBasedServers || !urlBasedServers.length) {
|
||||
return false;
|
||||
} else if (!servers.length || !activeServer) {
|
||||
// no current valid server
|
||||
return true;
|
||||
}
|
||||
|
||||
const newServer = urlBasedServers[0];
|
||||
|
||||
let exists = servers.some(
|
||||
GoogleCloudUtilServers.isEqualServer.bind(undefined, newServer)
|
||||
);
|
||||
|
||||
return !exists;
|
||||
};
|
||||
|
||||
export default function useServer({
|
||||
@@ -64,14 +106,29 @@ export default function useServer({
|
||||
} = {}) {
|
||||
// Hooks
|
||||
const servers = useSelector(state => state && state.servers);
|
||||
const previousServers = usePrevious(servers);
|
||||
const dispatch = useDispatch();
|
||||
|
||||
const { appConfig = {} } = useContext(AppContext);
|
||||
|
||||
const server = getActiveServer(servers);
|
||||
const activeServer = getActiveServer(servers);
|
||||
const urlBasedServers =
|
||||
getServers(appConfig, project, location, dataset, dicomStore) || [];
|
||||
const shouldUpdateServer = useServerFromUrl(
|
||||
servers.servers,
|
||||
previousServers,
|
||||
activeServer,
|
||||
urlBasedServers,
|
||||
appConfig,
|
||||
project,
|
||||
location,
|
||||
dataset,
|
||||
dicomStore
|
||||
);
|
||||
|
||||
if (!server) {
|
||||
updateServer(appConfig, dispatch, project, location, dataset, dicomStore);
|
||||
} else {
|
||||
return server;
|
||||
if (shouldUpdateServer) {
|
||||
setServers(dispatch, urlBasedServers);
|
||||
} else if (isValidServer(activeServer, appConfig)) {
|
||||
return activeServer;
|
||||
}
|
||||
}
|
||||
@@ -29,6 +29,10 @@ class GoogleCloudApi {
|
||||
);
|
||||
}
|
||||
|
||||
getUrlPath(project, location, dataset, dicomStore) {
|
||||
`/projects/${project}/locations/${location}/datasets/${dataset}/dicomStores/${dicomStore}`;
|
||||
}
|
||||
|
||||
async doRequest(urlStr, config = {}, params = {}) {
|
||||
const url = new URL(urlStr);
|
||||
let data = null;
|
||||
|
||||
@@ -29,4 +29,31 @@ const getServers = (data, name) => {
|
||||
];
|
||||
};
|
||||
|
||||
export { getServers };
|
||||
const isValidServer = server => {
|
||||
return (
|
||||
server &&
|
||||
!!server.dataset &&
|
||||
!!server.dicomStore &&
|
||||
!!server.location &&
|
||||
!!server.project
|
||||
);
|
||||
};
|
||||
|
||||
const isEqualServer = (server = {}, toCompare = {}) => {
|
||||
const serverLength = Object.keys(server).length;
|
||||
const toCompareLength = Object.keys(toCompare).length;
|
||||
|
||||
if (!serverLength || !toCompareLength) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return (
|
||||
server.dataset === toCompare.dataset &&
|
||||
server.dataset === toCompare.dataset &&
|
||||
server.dicomStore === toCompare.dicomStore &&
|
||||
server.location === toCompare.location &&
|
||||
server.project === toCompare.project
|
||||
);
|
||||
};
|
||||
|
||||
export { getServers, isValidServer, isEqualServer };
|
||||
@@ -65,6 +65,19 @@ const ROUTES_DEF = {
|
||||
return !!appConfig.enableGoogleCloudAdapter;
|
||||
},
|
||||
},
|
||||
list: {
|
||||
path:
|
||||
'/projects/:project/locations/:location/datasets/:dataset/dicomStores/:dicomStore',
|
||||
component: StudyListRouting,
|
||||
condition: appConfig => {
|
||||
const showList =
|
||||
appConfig.showStudyList !== undefined
|
||||
? appConfig.showStudyList
|
||||
: true;
|
||||
|
||||
return showList && !!appConfig.enableGoogleCloudAdapter;
|
||||
},
|
||||
},
|
||||
},
|
||||
};
|
||||
|
||||
@@ -92,23 +105,33 @@ const getRoutes = appConfig => {
|
||||
return routes;
|
||||
};
|
||||
|
||||
const parsePath = (path, server, params) => {
|
||||
let _path = path;
|
||||
const _paramsCopy = Object.assign({}, server, params);
|
||||
|
||||
for (let key in _paramsCopy) {
|
||||
_path = UrlUtil.paramString.replaceParam(_path, key, _paramsCopy[key]);
|
||||
}
|
||||
|
||||
return _path;
|
||||
};
|
||||
|
||||
const parseViewerPath = (appConfig = {}, server = {}, params) => {
|
||||
let viewerPath = ROUTES_DEF.default.viewer.path;
|
||||
if (appConfig.enableGoogleCloudAdapter) {
|
||||
viewerPath = ROUTES_DEF.gcloud.viewer.path;
|
||||
}
|
||||
|
||||
const _paramsCopy = Object.assign({}, server, params);
|
||||
|
||||
for (let key in _paramsCopy) {
|
||||
viewerPath = UrlUtil.paramString.replaceParam(
|
||||
viewerPath,
|
||||
key,
|
||||
_paramsCopy[key]
|
||||
);
|
||||
}
|
||||
|
||||
return viewerPath;
|
||||
return parsePath(viewerPath, server, params);
|
||||
};
|
||||
|
||||
export { getRoutes, parseViewerPath, reload };
|
||||
const parseStudyListPath = (appConfig = {}, server = {}, params) => {
|
||||
let studyListPath = ROUTES_DEF.default.list.path;
|
||||
if (appConfig.enableGoogleCloudAdapter) {
|
||||
studyListPath = ROUTES_DEF.gcloud.list.path || studyListPath;
|
||||
}
|
||||
|
||||
return parsePath(studyListPath, server, params);
|
||||
};
|
||||
|
||||
export { getRoutes, parseViewerPath, parseStudyListPath, reload };
|
||||
@@ -2,17 +2,26 @@ import React, { useContext } from 'react';
|
||||
import PropTypes from 'prop-types';
|
||||
import { withRouter } from 'react-router-dom';
|
||||
import ConnectedStudyList from './ConnectedStudyList';
|
||||
|
||||
import useServer from '../customHooks/useServer';
|
||||
import OHIF from '@ohif/core';
|
||||
const { urlUtil: UrlUtil } = OHIF.utils;
|
||||
|
||||
// Contexts
|
||||
import AppContext from '../context/AppContext';
|
||||
|
||||
function StudyListRouting({ location }) {
|
||||
function StudyListRouting({ match: routeMatch, location: routeLocation }) {
|
||||
const {
|
||||
project,
|
||||
location,
|
||||
dataset,
|
||||
dicomStore,
|
||||
studyInstanceUids,
|
||||
seriesInstanceUids,
|
||||
} = routeMatch.params;
|
||||
const server = useServer({ project, location, dataset, dicomStore });
|
||||
const { appConfig = {} } = useContext(AppContext);
|
||||
|
||||
const filters = UrlUtil.queryString.getQueryFilters(location);
|
||||
const filters = UrlUtil.queryString.getQueryFilters(routeLocation);
|
||||
|
||||
let studyListFunctionsEnabled = false;
|
||||
if (appConfig.studyListFunctionsEnabled) {
|
||||
|
||||
@@ -13,6 +13,7 @@ import ConnectedDicomFilesUploader from '../googleCloud/ConnectedDicomFilesUploa
|
||||
import ConnectedDicomStorePicker from '../googleCloud/ConnectedDicomStorePicker';
|
||||
import filesToStudies from '../lib/filesToStudies.js';
|
||||
|
||||
const { urlUtil: UrlUtil } = OHIF.utils;
|
||||
// Contexts
|
||||
import UserManagerContext from '../context/UserManagerContext';
|
||||
import WhiteLabellingContext from '../context/WhiteLabellingContext';
|
||||
@@ -202,9 +203,27 @@ class StudyListWithData extends Component {
|
||||
const viewerPath = RoutesUtil.parseViewerPath(appConfig, server, {
|
||||
studyInstanceUids: studyInstanceUID,
|
||||
});
|
||||
this.props.history.push(viewerPath);
|
||||
|
||||
if (UrlUtil.paramString.isValidPath(viewerPath)) {
|
||||
this.props.history.push(viewerPath);
|
||||
}
|
||||
};
|
||||
|
||||
updateURL(modalOpened) {
|
||||
if (!modalOpened) {
|
||||
const { appConfig = {} } = this.context;
|
||||
const { server } = this.props;
|
||||
const listPath = RoutesUtil.parseStudyListPath(appConfig, server);
|
||||
|
||||
if (UrlUtil.paramString.isValidPath(listPath)) {
|
||||
const { location = {} } = this.props.history;
|
||||
if (location.pathname !== listPath) {
|
||||
this.props.history.replace(listPath);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
onSearch = searchData => {
|
||||
this.searchForStudies(searchData);
|
||||
};
|
||||
@@ -235,9 +254,12 @@ class StudyListWithData extends Component {
|
||||
let healthCareApiWindows = null;
|
||||
|
||||
if (appConfig.enableGoogleCloudAdapter) {
|
||||
const modalOpened = this.state.modalComponentId === 'DicomStorePicker';
|
||||
this.updateURL(modalOpened);
|
||||
|
||||
healthCareApiWindows = (
|
||||
<ConnectedDicomStorePicker
|
||||
isOpen={this.state.modalComponentId === 'DicomStorePicker'}
|
||||
isOpen={modalOpened}
|
||||
onClose={this.closeModals}
|
||||
/>
|
||||
);
|
||||
|
||||
@@ -15526,10 +15526,10 @@ react-transition-group@^4.1.1:
|
||||
loose-envify "^1.4.0"
|
||||
prop-types "^15.6.2"
|
||||
|
||||
react-vtkjs-viewport@^0.3.5:
|
||||
version "0.3.5"
|
||||
resolved "https://registry.yarnpkg.com/react-vtkjs-viewport/-/react-vtkjs-viewport-0.3.5.tgz#772a5e51e1a8f7e9ca170e9044bee28debf04002"
|
||||
integrity sha512-JeSrS0oaV5fcHTN8VOGzP4ayM0K4PNoPrEYpyw9CGHbBFivshEiQnbyDqpPxkbHJrLCf2dNKTqbI3A5cL4iTZQ==
|
||||
react-vtkjs-viewport@^0.3.6:
|
||||
version "0.3.6"
|
||||
resolved "https://registry.yarnpkg.com/react-vtkjs-viewport/-/react-vtkjs-viewport-0.3.6.tgz#69df6c5c8808a64dc005d77e8058f9a99eaaca02"
|
||||
integrity sha512-tK6thFTiStFhfYuKBf6xEPRUYf+iZVcujzDElbMFqggRC5PgzcLfYZFAI/bI+9ju7VVyuVazhADu2KHJZYsuEg==
|
||||
dependencies:
|
||||
date-fns "^2.2.1"
|
||||
gl-matrix "^3.1.0"
|
||||
|
||||
Reference in new issue
Block a user