diff --git a/package.json b/package.json
index e156e1c04..317ebc67d 100644
--- a/package.json
+++ b/package.json
@@ -101,6 +101,7 @@
"ohif-core": "0.9.1",
"oidc-client": "1.7.x",
"prop-types": "^15.7.2",
+ "react-dropzone": "^10.1.5",
"react-i18next": "^10.11.0",
"react-redux": "^7.1.0",
"react-resize-detector": "^4.2.0",
diff --git a/src/OHIFStandaloneViewer.js b/src/OHIFStandaloneViewer.js
index d933a5de3..c5f8bc716 100644
--- a/src/OHIFStandaloneViewer.js
+++ b/src/OHIFStandaloneViewer.js
@@ -9,6 +9,7 @@ import { ViewerbaseDragDropContext } from 'react-viewerbase';
// import asyncComponent from './components/AsyncComponent.js'
import IHEInvokeImageDisplay from './routes/IHEInvokeImageDisplay.js';
import ViewerRouting from './routes/ViewerRouting.js';
+import ViewerLocalFileData from './connectedComponents/ViewerLocalFileData.js';
import StudyListRouting from './studylist/StudyListRouting.js';
import StandaloneRouting from './routes/StandaloneRouting.js';
import CallbackPage from './routes/CallbackPage.js';
@@ -96,6 +97,10 @@ class OHIFStandaloneViewer extends Component {
* See http://reactcommunity.org/react-transition-group/with-react-router/
*/
const routes = [
+ {
+ path: '/local',
+ Component: ViewerLocalFileData,
+ },
{
path: '/viewer',
Component: StandaloneRouting,
diff --git a/src/connectedComponents/ViewerLocalFileData.css b/src/connectedComponents/ViewerLocalFileData.css
new file mode 100644
index 000000000..2e6f396fc
--- /dev/null
+++ b/src/connectedComponents/ViewerLocalFileData.css
@@ -0,0 +1,15 @@
+.drag-drop-instructions {
+ width: 100%;
+ height: 100%;
+ display: flex;
+ justify-content: center;
+ align-items: center;
+}
+
+.drag-drop-instructions h3 {
+ color: var(--active-color);
+}
+
+.drag-drop-instructions h4 {
+ color: var(--text-secondary-color);
+}
diff --git a/src/connectedComponents/ViewerLocalFileData.js b/src/connectedComponents/ViewerLocalFileData.js
new file mode 100644
index 000000000..eb49fc2ea
--- /dev/null
+++ b/src/connectedComponents/ViewerLocalFileData.js
@@ -0,0 +1,117 @@
+import React, { Component } from 'react';
+import { metadata, utils } from 'ohif-core';
+
+import ConnectedViewer from './ConnectedViewer.js';
+import PropTypes from 'prop-types';
+import { extensionManager } from './../App.js';
+import Dropzone from 'react-dropzone';
+import filesToStudies from '../lib/filesToStudies';
+import './ViewerLocalFileData.css';
+import { withTranslation } from 'react-i18next';
+
+const { OHIFStudyMetadata } = metadata;
+const { studyMetadataManager, updateMetaDataManager } = utils;
+
+class ViewerLocalFileData extends Component {
+ static propTypes = {
+ studies: PropTypes.array,
+ };
+
+ state = {
+ studies: null,
+ loading: false,
+ error: null,
+ };
+
+ updateStudies = studies => {
+ // Render the viewer when the data is ready
+ studyMetadataManager.purge();
+
+ // Map studies to new format, update metadata manager?
+ const updatedStudies = studies.map(study => {
+ const studyMetadata = new OHIFStudyMetadata(
+ study,
+ study.studyInstanceUid
+ );
+ const sopClassHandlerModules =
+ extensionManager.modules['sopClassHandlerModule'];
+
+ study.displaySets =
+ study.displaySets ||
+ studyMetadata.createDisplaySets(sopClassHandlerModules);
+ studyMetadata.setDisplaySets(study.displaySets);
+
+ // Updates WADO-RS metaDataManager
+ updateMetaDataManager(study);
+
+ studyMetadataManager.add(studyMetadata);
+
+ return study;
+ });
+
+ this.setState({
+ studies: updatedStudies,
+ });
+ };
+
+ render() {
+ const onDrop = async acceptedFiles => {
+ this.setState({ loading: true });
+
+ const studies = await filesToStudies(acceptedFiles);
+ const updatedStudies = this.updateStudies(studies);
+
+ if (!updatedStudies) {
+ return;
+ }
+
+ this.setState({ studies: updatedStudies, loading: false });
+ };
+
+ if (this.state.error) {
+ return
Error: {JSON.stringify(this.state.error)}
;
+ }
+
+ return (
+
+ {({ getRootProps, getInputProps }) => (
+
+ {this.state.studies ? (
+
a.studyInstanceUid)
+ }
+ />
+ ) : (
+
+
+ {this.state.loading ? (
+
{this.props.t('Loading...')}
+ ) : (
+ <>
+
+ {this.props.t(
+ 'Drag and Drop DICOM files here to load them in the Viewer'
+ )}
+
+
+ {this.props.t(
+ "Or click to load the browser's file selector"
+ )}
+
+ >
+ )}
+
+
+
+ )}
+
+ )}
+
+ );
+ }
+}
+
+export default withTranslation('Common')(ViewerLocalFileData);
diff --git a/src/lib/filesToStudies.js b/src/lib/filesToStudies.js
new file mode 100644
index 000000000..03d227843
--- /dev/null
+++ b/src/lib/filesToStudies.js
@@ -0,0 +1,152 @@
+import cornerstone from 'cornerstone-core';
+import cornerstoneWADOImageLoader from 'cornerstone-wado-image-loader';
+import * as dcmjs from 'dcmjs';
+
+function datasetsToStudies(datasets) {
+ const StudyInstanceUIDs = new Set();
+ datasets.forEach(ds => {
+ StudyInstanceUIDs.add(ds.StudyInstanceUID);
+ });
+
+ const studies = [];
+ Array.from(StudyInstanceUIDs).forEach(studyInstanceUid => {
+ const studyDatasets = datasets.filter(
+ ds => ds.StudyInstanceUID === studyInstanceUid
+ );
+ const firstDataset = studyDatasets[0];
+ const study = {
+ studyInstanceUid: firstDataset.StudyInstanceUID,
+ studyDate: firstDataset.StudyDate,
+ studyTime: firstDataset.StudyTime,
+ accessionNumber: firstDataset.AccessionNumber,
+ referringPhysicianName: firstDataset.ReferringPhysicianName,
+ patientName: firstDataset.PatientName,
+ patientId: firstDataset.PatientID,
+ patientBirthdate: firstDataset.PatientBirthDate,
+ patientSex: firstDataset.PatientSex,
+ studyId: firstDataset.StudyID,
+ studyDescription: firstDataset.StudyDescription,
+ //numberOfStudyRelatedSeries: DICOMWeb.getString(study['00201206']),
+ //numberOfStudyRelatedInstances: DICOMWeb.getString(study['00201208']),
+ // modality: DICOMWeb.getString(study['00080060']),
+ // modalitiesInStudy: DICOMWeb.getString(study['00080061']),
+ //modalities:
+ seriesList: [],
+ };
+
+ const SeriesInstanceUIDs = new Set();
+ studyDatasets.forEach(ds => {
+ SeriesInstanceUIDs.add(ds.SeriesInstanceUID);
+ });
+
+ Array.from(SeriesInstanceUIDs).forEach(seriesInstanceUid => {
+ const seriesDatasets = studyDatasets.filter(
+ ds => ds.SeriesInstanceUID === seriesInstanceUid
+ );
+
+ const SOPInstanceUIDs = new Set();
+ seriesDatasets.forEach(ds => {
+ SOPInstanceUIDs.add(ds.SOPInstanceUID);
+
+ study.seriesList.push({
+ seriesInstanceUid: ds.SeriesInstanceUID,
+ seriesDescription: ds.SeriesDescription,
+ seriesNumber: ds.SeriesNumber,
+ instances: [],
+ });
+ });
+
+ Array.from(SOPInstanceUIDs).forEach(sopInstanceUid => {
+ const instance = seriesDatasets.find(
+ a => a.SOPInstanceUID === sopInstanceUid
+ );
+ const series = study.seriesList.find(
+ a => a.seriesInstanceUid === seriesInstanceUid
+ );
+
+ series.instances.push({
+ sopInstanceUid: instance.SOPInstanceUID,
+ sopClassUid: instance.SOPClassUID,
+ rows: instance.Rows,
+ columns: instance.Columns,
+ numberOfFrames: instance.NumberOfFrames,
+ instanceNumber: instance.InstanceNumber,
+ getImageId: () => instance.imageId, // TODO: Change getImageId to check for instance.imageId property first.
+ /*imageType: DICOMWeb.getString(instance['00080008']),
+ modality: DICOMWeb.getString(instance['00080060']),
+ instanceNumber: DICOMWeb.getNumber(instance['00200013']),
+ imagePositionPatient: DICOMWeb.getString(instance['00200032']),
+ imageOrientationPatient: DICOMWeb.getString(instance['00200037']),
+ frameOfReferenceUID: DICOMWeb.getString(instance['00200052']),
+ sliceLocation: DICOMWeb.getNumber(instance['00201041']),
+ samplesPerPixel: DICOMWeb.getNumber(instance['00280002']),
+ photometricInterpretation: DICOMWeb.getString(instance['00280004']),
+ planarConfiguration: DICOMWeb.getNumber(instance['00280006']),
+ pixelSpacing: DICOMWeb.getString(instance['00280030']),
+ pixelAspectRatio: DICOMWeb.getString(instance['00280034']),
+ bitsAllocated: DICOMWeb.getNumber(instance['00280100']),
+ bitsStored: DICOMWeb.getNumber(instance['00280101']),
+ highBit: DICOMWeb.getNumber(instance['00280102']),
+ pixelRepresentation: DICOMWeb.getNumber(instance['00280103']),
+ smallestPixelValue: DICOMWeb.getNumber(instance['00280106']),
+ largestPixelValue: DICOMWeb.getNumber(instance['00280107']),
+ windowCenter: DICOMWeb.getString(instance['00281050']),
+ windowWidth: DICOMWeb.getString(instance['00281051']),
+ rescaleIntercept: DICOMWeb.getNumber(instance['00281052']),
+ rescaleSlope: DICOMWeb.getNumber(instance['00281053']),
+ rescaleType: DICOMWeb.getNumber(instance['00281054']),
+ sourceImageInstanceUid: getSourceImageInstanceUid(instance),
+ laterality: DICOMWeb.getString(instance['00200062']),
+ viewPosition: DICOMWeb.getString(instance['00185101']),
+ acquisitionDateTime: DICOMWeb.getString(instance['0008002A']),
+ frameIncrementPointer: getFrameIncrementPointer(instance['00280009']),
+ frameTime: DICOMWeb.getNumber(instance['00181063']),
+ frameTimeVector: parseFloatArray(
+ DICOMWeb.getString(instance['00181065'])
+ ),
+ sliceThickness: DICOMWeb.getNumber(instance['00180050']),
+ spacingBetweenSlices: DICOMWeb.getString(instance['00180088']),
+ lossyImageCompression: DICOMWeb.getString(instance['00282110']),
+ derivationDescription: DICOMWeb.getString(instance['00282111']),
+ lossyImageCompressionRatio: DICOMWeb.getString(instance['00282112']),
+ lossyImageCompressionMethod: DICOMWeb.getString(instance['00282114']),
+ echoNumber: DICOMWeb.getString(instance['00180086']),
+ contrastBolusAgent: DICOMWeb.getString(instance['00180010']),
+ radiopharmaceuticalInfo: getRadiopharmaceuticalInfo(instance),
+ wadouri: WADOProxy.convertURL(wadouri, server),
+ wadorsuri: WADOProxy.convertURL(wadorsuri, server),*/
+ });
+ });
+ });
+
+ studies.push(study);
+ });
+
+ console.warn(studies);
+
+ return studies;
+}
+
+export default async function filesToStudies(files) {
+ const imagePromises = files.map(file => {
+ const imageId = cornerstoneWADOImageLoader.wadouri.fileManager.add(file);
+ return cornerstone.loadAndCacheImage(imageId);
+ });
+
+ const images = await Promise.all(imagePromises);
+ const datasets = images.map(image => {
+ const arrayBuffer = image.data.byteArray.buffer;
+ const dicomData = dcmjs.data.DicomMessage.readFile(arrayBuffer);
+ const dataset = dcmjs.data.DicomMetaDictionary.naturalizeDataset(
+ dicomData.dict
+ );
+ dataset._meta = dcmjs.data.DicomMetaDictionary.namifyDataset(
+ dicomData.meta
+ );
+ dataset.imageId = image.imageId;
+
+ return dataset;
+ });
+
+ return datasetsToStudies(datasets);
+}
diff --git a/src/studylist/StudyListWithData.js b/src/studylist/StudyListWithData.js
index 3f97015cf..d855eb71d 100644
--- a/src/studylist/StudyListWithData.js
+++ b/src/studylist/StudyListWithData.js
@@ -1,5 +1,6 @@
import React, { Component } from 'react';
import PropTypes from 'prop-types';
+import Dropzone from 'react-dropzone';
import OHIF from 'ohif-core';
import { withRouter } from 'react-router-dom';
import { withTranslation } from 'react-i18next';
@@ -8,6 +9,7 @@ import ConnectedHeader from '../connectedComponents/ConnectedHeader.js';
import moment from 'moment';
import ConnectedDicomFilesUploader from '../googleCloud/ConnectedDicomFilesUploader';
import ConnectedDicomStorePicker from '../googleCloud/ConnectedDicomStorePicker';
+import filesToStudies from '../lib/filesToStudies.js';
class StudyListWithData extends Component {
state = {
@@ -171,6 +173,19 @@ class StudyListWithData extends Component {
};
render() {
+ const onDrop = async acceptedFiles => {
+ // Do something with the files
+ console.warn(acceptedFiles);
+
+ try {
+ const studies = await filesToStudies(acceptedFiles);
+
+ this.setState({ studies });
+ } catch (error) {
+ this.setState({ error });
+ }
+ };
+
if (this.state.error) {
return Error: {JSON.stringify(this.state.error)}
;
} else if (this.state.studies === null && !this.state.modalComponentId) {
@@ -216,24 +231,44 @@ class StudyListWithData extends Component {
);
}
+ console.warn(this.state.studies);
+
const studyList = (
-
-
- {healthCareApiButtons}
- {healthCareApiWindows}
-
-
+
+ {({ getRootProps, getInputProps }) => (
+
+ {this.state.studies ? (
+
+ {healthCareApiButtons}
+ {healthCareApiWindows}
+
+ ) : (
+
+
+ {this.props.t(
+ 'Drag and Drop DICOM files here to load them in the Viewer'
+ )}
+
+
+ {this.props.t("Or click to load the browser's file selector")}
+
+
+
+ )}
+
+ )}
+
);
return (
<>
diff --git a/yarn.lock b/yarn.lock
index 5bd22c4f2..d5a95fc2f 100644
--- a/yarn.lock
+++ b/yarn.lock
@@ -894,7 +894,7 @@
dependencies:
regenerator-runtime "^0.13.2"
-"@babel/runtime@^7.0.0", "@babel/runtime@^7.1.2", "@babel/runtime@^7.2.0", "@babel/runtime@^7.3.1", "@babel/runtime@^7.3.4", "@babel/runtime@^7.4.0", "@babel/runtime@^7.4.2", "@babel/runtime@^7.4.5":
+"@babel/runtime@^7.0.0", "@babel/runtime@^7.1.2", "@babel/runtime@^7.2.0", "@babel/runtime@^7.3.1", "@babel/runtime@^7.3.4", "@babel/runtime@^7.4.0", "@babel/runtime@^7.4.2", "@babel/runtime@^7.4.5", "@babel/runtime@^7.5.4":
version "7.5.4"
resolved "https://registry.yarnpkg.com/@babel/runtime/-/runtime-7.5.4.tgz#cb7d1ad7c6d65676e66b47186577930465b5271b"
integrity sha512-Na84uwyImZZc3FKf4aUF1tysApzwf3p2yuFBIyBfbzT5glzKTdvYI4KVW4kcgjrzoGUjC7w3YyCHcJKaRxsr2Q==
@@ -1518,11 +1518,11 @@
loader-utils "^1.1.0"
"@tanem/react-nprogress@^1.1.25":
- version "1.1.30"
- resolved "https://registry.yarnpkg.com/@tanem/react-nprogress/-/react-nprogress-1.1.30.tgz#fd10c20f2c98c3f8f78df4c1ba842105f2b09021"
- integrity sha512-OGN0WNNTGvA7kAUSU1Ajn0BBCDVxZoU1xGTZSQgjwqDeeRChXyidt8cuB85yvFxhCrzyVf8ovM3e5uDX43ROaQ==
+ version "1.1.31"
+ resolved "https://registry.yarnpkg.com/@tanem/react-nprogress/-/react-nprogress-1.1.31.tgz#967bbf0182a1af562f4667fea0c0ee31ea34e078"
+ integrity sha512-v2C4+E9/Od2iGsrEWdbBBLTEYl7TvRos+I7XfnF2W1421F1MoUH0hsDrU7leqoEKQhrimlKDU54hwV09egKhgw==
dependencies:
- "@babel/runtime" "^7.4.5"
+ "@babel/runtime" "^7.5.4"
hoist-non-react-statics "^3.3.0"
prop-types "^15.7.2"
@@ -2387,6 +2387,13 @@ atob@^2.1.1:
resolved "https://registry.yarnpkg.com/atob/-/atob-2.1.2.tgz#6d9517eb9e030d2436666651e86bd9f6f13533c9"
integrity sha512-Wm6ukoaOGJi/73p/cl2GvLjTI5JM1k/O14isD73YML8StrH/7/lRFgmg8nICZgD3bZZvjwCGxtMOD3wWNAu8cg==
+attr-accept@^1.1.3:
+ version "1.1.3"
+ resolved "https://registry.yarnpkg.com/attr-accept/-/attr-accept-1.1.3.tgz#48230c79f93790ef2775fcec4f0db0f5db41ca52"
+ integrity sha512-iT40nudw8zmCweivz6j58g+RT33I4KbaIvRUhjNmDwO2WmsQUxFEZZYZ5w3vXe5x5MX9D7mfvA/XaLOZYFR9EQ==
+ dependencies:
+ core-js "^2.5.0"
+
autoprefixer@^9.4.9, autoprefixer@^9.5.1:
version "9.6.1"
resolved "https://registry.yarnpkg.com/autoprefixer/-/autoprefixer-9.6.1.tgz#51967a02d2d2300bb01866c1611ec8348d355a47"
@@ -3797,7 +3804,7 @@ core-js@^1.0.0:
resolved "https://registry.yarnpkg.com/core-js/-/core-js-1.2.7.tgz#652294c14651db28fa93bd2d5ff2983a4f08c636"
integrity sha1-ZSKUwUZR2yj6k70tX/KYOk8IxjY=
-core-js@^2.4.0, core-js@^2.5.7, core-js@^2.6.5:
+core-js@^2.4.0, core-js@^2.5.0, core-js@^2.5.7, core-js@^2.6.5:
version "2.6.9"
resolved "https://registry.yarnpkg.com/core-js/-/core-js-2.6.9.tgz#6b4b214620c834152e179323727fc19741b084f2"
integrity sha512-HOpZf6eXmnl7la+cUdMnLvUxKNqLUzJvgIziQ0DiF3JwSImNphIqdGqzj6hIKyX04MmV0poclQ7+wjWvxQyR2A==
@@ -4815,9 +4822,9 @@ ee-first@1.1.1:
integrity sha1-WQxhFWsK4vTwJVcyoViyZrxWsh0=
electron-to-chromium@^1.3.150:
- version "1.3.188"
- resolved "https://registry.yarnpkg.com/electron-to-chromium/-/electron-to-chromium-1.3.188.tgz#e28e1afe4bb229989e280bfd3b395c7ec03c8b7a"
- integrity sha512-tEQcughYIMj8WDMc59EGEtNxdGgwal/oLLTDw+NEqJRJwGflQvH3aiyiexrWeZOETP4/ko78PVr6gwNhdozvuQ==
+ version "1.3.189"
+ resolved "https://registry.yarnpkg.com/electron-to-chromium/-/electron-to-chromium-1.3.189.tgz#aa84055eb36d364a68852ad2d25e1315a1d06196"
+ integrity sha512-C26Kv6/rLNmGDaPR5HORMtTQat9aWBBKjQk9aFtN1Bk6cQBSw8cYdsel/mcrQlNlMMjt1sAKsTYqf77+sK2uTw==
elegant-spinner@^1.0.1:
version "1.0.1"
@@ -5656,6 +5663,13 @@ file-loader@3.0.1:
loader-utils "^1.0.2"
schema-utils "^1.0.0"
+file-selector@^0.1.11:
+ version "0.1.12"
+ resolved "https://registry.yarnpkg.com/file-selector/-/file-selector-0.1.12.tgz#fe726547be219a787a9dcc640575a04a032b1fd0"
+ integrity sha512-Kx7RTzxyQipHuiqyZGf+Nz4vY9R1XGxuQl/hLoJwq+J4avk/9wxxgZyHKtbyIPJmbD4A66DWGYfyykWNpcYutQ==
+ dependencies:
+ tslib "^1.9.0"
+
filename-regex@^2.0.0:
version "2.0.1"
resolved "https://registry.yarnpkg.com/filename-regex/-/filename-regex-2.0.1.tgz#c1c4b9bee3e09725ddb106b75c1e301fe2f18b26"
@@ -7148,9 +7162,9 @@ inquirer@6.2.2:
through "^2.3.6"
inquirer@^6.2.2:
- version "6.4.1"
- resolved "https://registry.yarnpkg.com/inquirer/-/inquirer-6.4.1.tgz#7bd9e5ab0567cd23b41b0180b68e0cfa82fc3c0b"
- integrity sha512-/Jw+qPZx4EDYsaT6uz7F4GJRNFMRdKNeUZw3ZnKV8lyuUgz/YWRCSUAJMZSVhSq4Ec0R2oYnyi6b3d4JXcL5Nw==
+ version "6.5.0"
+ resolved "https://registry.yarnpkg.com/inquirer/-/inquirer-6.5.0.tgz#2303317efc9a4ea7ec2e2df6f86569b734accf42"
+ integrity sha512-scfHejeG/lVZSpvCXpsB4j/wQNPM5JC8kiElOI0OUTwmc1RTpXr4H32/HOlQHcZiYl2z2VElwuCVDRG8vFmbnA==
dependencies:
ansi-escapes "^3.2.0"
chalk "^2.4.2"
@@ -7158,7 +7172,7 @@ inquirer@^6.2.2:
cli-width "^2.0.0"
external-editor "^3.0.3"
figures "^2.0.0"
- lodash "^4.17.11"
+ lodash "^4.17.12"
mute-stream "0.0.7"
run-async "^2.2.0"
rxjs "^6.4.0"
@@ -8771,6 +8785,11 @@ lie@~3.1.0:
dependencies:
immediate "~3.0.5"
+lines-and-columns@^1.1.6:
+ version "1.1.6"
+ resolved "https://registry.yarnpkg.com/lines-and-columns/-/lines-and-columns-1.1.6.tgz#1c00c743b433cd0a4e80758f7b64a57440d9ff00"
+ integrity sha1-HADHQ7QzzQpOgHWPe2SldEDZ/wA=
+
lint-staged@^8.2.1:
version "8.2.1"
resolved "https://registry.yarnpkg.com/lint-staged/-/lint-staged-8.2.1.tgz#752fcf222d9d28f323a3b80f1e668f3654ff221f"
@@ -9156,7 +9175,7 @@ lodash@4.17.11:
resolved "https://registry.yarnpkg.com/lodash/-/lodash-4.17.11.tgz#b39ea6229ef607ecd89e2c8df12536891cac9b8d"
integrity sha512-cQKh8igo5QUhZ7lg38DYWAxMvjSAKG0A8wGSVimP07SIUEK2UO+arSRKbRZWtelMtN5V0Hkwh5ryOto/SshYIg==
-"lodash@>=3.5 <5", lodash@^4.1.1, lodash@^4.17.10, lodash@^4.17.11, lodash@^4.17.4, lodash@^4.17.5, lodash@^4.2.1:
+"lodash@>=3.5 <5", lodash@^4.1.1, lodash@^4.17.10, lodash@^4.17.11, lodash@^4.17.12, lodash@^4.17.4, lodash@^4.17.5, lodash@^4.2.1:
version "4.17.14"
resolved "https://registry.yarnpkg.com/lodash/-/lodash-4.17.14.tgz#9ce487ae66c96254fe20b599f21b6816028078ba"
integrity sha512-mmKYbW3GLuJeX+iGP+Y7Gp1AiGHGbXHCOh/jZmrawMmsE7MS4znI3RL2FsjbqOyMayHInjOeykW7PEajUk1/xw==
@@ -10898,6 +10917,16 @@ parse-json@^4.0.0:
error-ex "^1.3.1"
json-parse-better-errors "^1.0.1"
+parse-json@^5.0.0:
+ version "5.0.0"
+ resolved "https://registry.yarnpkg.com/parse-json/-/parse-json-5.0.0.tgz#73e5114c986d143efa3712d4ea24db9a4266f60f"
+ integrity sha512-OOY5b7PAEFV0E2Fir1KOkxchnZNCdowAJgQ5NuxjpBKTRP3pQhwkrkxqQjeoKJ+fO7bCpmIZaogI4eZGDMEGOw==
+ dependencies:
+ "@babel/code-frame" "^7.0.0"
+ error-ex "^1.3.1"
+ json-parse-better-errors "^1.0.1"
+ lines-and-columns "^1.1.6"
+
parse-passwd@^1.0.0:
version "1.0.0"
resolved "https://registry.yarnpkg.com/parse-passwd/-/parse-passwd-1.0.0.tgz#6d5b934a456993b23d37f40a382d6f1666a8e5c6"
@@ -12468,6 +12497,15 @@ react-dom@^16.7.0:
prop-types "^15.6.2"
scheduler "^0.13.6"
+react-dropzone@^10.1.5:
+ version "10.1.5"
+ resolved "https://registry.yarnpkg.com/react-dropzone/-/react-dropzone-10.1.5.tgz#5f2817ab924b270010c7034fe01f49b6240b9c91"
+ integrity sha512-Hbe7soBc/i1fid7K3BU8T1oUJFnYO2AicS22F2MxcueMYDfKBWqZMr5ED3CoTAMs//9t2W30eyFiXm1h4wLCqA==
+ dependencies:
+ attr-accept "^1.1.3"
+ file-selector "^0.1.11"
+ prop-types "^15.7.2"
+
react-error-overlay@^5.1.6:
version "5.1.6"
resolved "https://registry.yarnpkg.com/react-error-overlay/-/react-error-overlay-5.1.6.tgz#0cd73407c5d141f9638ae1e0c63e7b2bf7e9929d"
@@ -12824,14 +12862,14 @@ read-pkg@^3.0.0:
path-type "^3.0.0"
read-pkg@^5.0.0, read-pkg@^5.1.1:
- version "5.1.1"
- resolved "https://registry.yarnpkg.com/read-pkg/-/read-pkg-5.1.1.tgz#5cf234dde7a405c90c88a519ab73c467e9cb83f5"
- integrity sha512-dFcTLQi6BZ+aFUaICg7er+/usEoqFdQxiEBsEMNGoipenihtxxtdrQuBXvyANCEI8VuUIVYFgeHGx9sLLvim4w==
+ version "5.2.0"
+ resolved "https://registry.yarnpkg.com/read-pkg/-/read-pkg-5.2.0.tgz#7bf295438ca5a33e56cd30e053b34ee7250c93cc"
+ integrity sha512-Ug69mNOpfvKDAc2Q8DRpMjjzdtrnv9HcSMX+4VsZxD1aZ6ZzrIE7rlzXBtWTyhULSMKg076AW6WR5iZpD0JiOg==
dependencies:
"@types/normalize-package-data" "^2.4.0"
normalize-package-data "^2.5.0"
- parse-json "^4.0.0"
- type-fest "^0.4.1"
+ parse-json "^5.0.0"
+ type-fest "^0.6.0"
read@1, read@~1.0.1, read@~1.0.7:
version "1.0.7"
@@ -12969,9 +13007,9 @@ redux-thunk@^2.3.0:
integrity sha512-km6dclyFnmcvxhAcrQV2AkZmPQjzPDjgVlQtR0EQjxZPyJ0BnMf3in1ryuR8A2qU0HldVRfxYXbFSKlI3N7Slw==
redux@^4.0.1:
- version "4.0.3"
- resolved "https://registry.yarnpkg.com/redux/-/redux-4.0.3.tgz#0ca18be085e6cf6ed50e445a125f85e8b26b266b"
- integrity sha512-v/Iaw67Pe+na+cZvcKvPxAKT1ww5kM+M09fmaCndCQC4Lo434AYb5975HJgJlp0D7dJxfYaLxMD4VwfpLOZ1Rw==
+ version "4.0.4"
+ resolved "https://registry.yarnpkg.com/redux/-/redux-4.0.4.tgz#4ee1aeb164b63d6a1bcc57ae4aa0b6e6fa7a3796"
+ integrity sha512-vKv4WdiJxOWKxK0yRoaK3Y4pxxB0ilzVx6dszU2W8wLxlb2yikRph4iV/ymtdJ6ZxpBLFbyrxklnT5yBbQSl3Q==
dependencies:
loose-envify "^1.4.0"
symbol-observable "^1.2.0"
@@ -14165,9 +14203,9 @@ spdx-expression-parse@^3.0.0:
spdx-license-ids "^3.0.0"
spdx-license-ids@^3.0.0:
- version "3.0.4"
- resolved "https://registry.yarnpkg.com/spdx-license-ids/-/spdx-license-ids-3.0.4.tgz#75ecd1a88de8c184ef015eafb51b5b48bfd11bb1"
- integrity sha512-7j8LYJLeY/Yb6ACbQ7F76qy5jHkp0U6jgBfJsk97bwWlVUnUWsAgpyaCvo17h0/RQGnQ036tVDomiwoI4pDkQA==
+ version "3.0.5"
+ resolved "https://registry.yarnpkg.com/spdx-license-ids/-/spdx-license-ids-3.0.5.tgz#3694b5804567a458d3c8045842a6358632f62654"
+ integrity sha512-J+FWzZoynJEXGphVIS+XEh3kFSjZX/1i9gFBaWQcB+/tmpe2qUsSBABpcxqxnAxFdiUFEgAX1bjYGQvIZmoz9Q==
spdy-transport@^3.0.0:
version "3.0.0"
@@ -15098,16 +15136,16 @@ type-check@~0.3.2:
dependencies:
prelude-ls "~1.1.2"
-type-fest@^0.4.1:
- version "0.4.1"
- resolved "https://registry.yarnpkg.com/type-fest/-/type-fest-0.4.1.tgz#8bdf77743385d8a4f13ba95f610f5ccd68c728f8"
- integrity sha512-IwzA/LSfD2vC1/YDYMv/zHP4rDF1usCwllsDpbolT3D4fUepIO7f9K70jjmUewU/LmGUKJcwcVtDCpnKk4BPMw==
-
type-fest@^0.5.0:
version "0.5.2"
resolved "https://registry.yarnpkg.com/type-fest/-/type-fest-0.5.2.tgz#d6ef42a0356c6cd45f49485c3b6281fc148e48a2"
integrity sha512-DWkS49EQKVX//Tbupb9TFa19c7+MK1XmzkrZUR8TAktmE/DizXoaoJV6TZ/tSIPXipqNiRI6CyAe7x69Jb6RSw==
+type-fest@^0.6.0:
+ version "0.6.0"
+ resolved "https://registry.yarnpkg.com/type-fest/-/type-fest-0.6.0.tgz#8d2a2370d3df886eb5c90ada1c5bf6188acf838b"
+ integrity sha512-q+MB8nYR1KDLrgr4G5yemftpMC7/QLqVndBmEEdqzmNj5dcFOO4Oo8qlwZE3ULT3+Zim1F8Kq4cBnikNhlCMlg==
+
type-is@~1.6.17, type-is@~1.6.18:
version "1.6.18"
resolved "https://registry.yarnpkg.com/type-is/-/type-is-1.6.18.tgz#4e552cd05df09467dcbc4ef739de89f2cf37c131"