diff --git a/web/package.json b/web/package.json index 98f786e8..e6adad40 100644 --- a/web/package.json +++ b/web/package.json @@ -38,6 +38,7 @@ "react-dom": "^17.0.1", "react-hook-form": "^6.11.0", "react-hooks-global-state": "^1.0.1", + "react-responsive": "^8.1.1", "react-router": "^5.2.0", "react-router-dom": "^5.2.0", "react-scripts": "^4.0.0", diff --git a/web/public/illustrations/alcohol__cotton_swabs__medical_tape.png b/web/public/illustrations/alcohol__cotton_swabs__medical_tape.png new file mode 100644 index 00000000..46c8c585 Binary files /dev/null and b/web/public/illustrations/alcohol__cotton_swabs__medical_tape.png differ diff --git a/web/public/illustrations/chip.png b/web/public/illustrations/chip.png deleted file mode 100644 index 62a00fdb..00000000 Binary files a/web/public/illustrations/chip.png and /dev/null differ diff --git a/web/public/illustrations/ec2.png b/web/public/illustrations/ec2.png deleted file mode 100644 index b12c9c6b..00000000 Binary files a/web/public/illustrations/ec2.png and /dev/null differ diff --git a/web/public/illustrations/ec2_ten20.png b/web/public/illustrations/ec2_ten20.png new file mode 100644 index 00000000..c4a3e321 Binary files /dev/null and b/web/public/illustrations/ec2_ten20.png differ diff --git a/web/public/illustrations/electrode.png b/web/public/illustrations/electrode.png deleted file mode 100644 index 260187e3..00000000 Binary files a/web/public/illustrations/electrode.png and /dev/null differ diff --git a/web/public/illustrations/gauze_electrodes.png b/web/public/illustrations/gauze_electrodes.png index 3606fc50..82fd6ef0 100644 Binary files a/web/public/illustrations/gauze_electrodes.png and b/web/public/illustrations/gauze_electrodes.png differ diff --git a/web/public/illustrations/gauze_pads.png b/web/public/illustrations/gauze_pads.png deleted file mode 100644 index 8a596295..00000000 Binary files a/web/public/illustrations/gauze_pads.png and /dev/null differ diff --git a/web/public/illustrations/hypafix.png b/web/public/illustrations/hypafix.png deleted file mode 100644 index f45bf4f0..00000000 Binary files a/web/public/illustrations/hypafix.png and /dev/null differ diff --git a/web/public/illustrations/hypafix__gauze_wrap.png b/web/public/illustrations/hypafix__gauze_wrap.png new file mode 100644 index 00000000..2d20f9f7 Binary files /dev/null and b/web/public/illustrations/hypafix__gauze_wrap.png differ diff --git a/web/public/illustrations/measuring_tape.png b/web/public/illustrations/measuring_tape.png deleted file mode 100644 index 9a207fc7..00000000 Binary files a/web/public/illustrations/measuring_tape.png and /dev/null differ diff --git a/web/public/illustrations/medical_tape.png b/web/public/illustrations/medical_tape.png deleted file mode 100644 index 44bb1372..00000000 Binary files a/web/public/illustrations/medical_tape.png and /dev/null differ diff --git a/web/public/illustrations/open_bci__electrodes__batteries.png b/web/public/illustrations/open_bci__electrodes__batteries.png new file mode 100644 index 00000000..2ab98c7a Binary files /dev/null and b/web/public/illustrations/open_bci__electrodes__batteries.png differ diff --git a/web/public/illustrations/pen_tape.png b/web/public/illustrations/pen_tape.png new file mode 100644 index 00000000..c3db0d13 Binary files /dev/null and b/web/public/illustrations/pen_tape.png differ diff --git a/web/public/illustrations/sd.png b/web/public/illustrations/sd.png index c6f7d6ca..fd8d1b5b 100644 Binary files a/web/public/illustrations/sd.png and b/web/public/illustrations/sd.png differ diff --git a/web/public/img/cyton_connections.png b/web/public/img/cyton_connections.png new file mode 100644 index 00000000..d59bcd91 Binary files /dev/null and b/web/public/img/cyton_connections.png differ diff --git a/web/public/img/ganglion_connections.png b/web/public/img/ganglion_connections.png new file mode 100644 index 00000000..06d08a91 Binary files /dev/null and b/web/public/img/ganglion_connections.png differ diff --git a/web/public/img/impedance_btn.png b/web/public/img/impedance_btn.png new file mode 100644 index 00000000..f877989a Binary files /dev/null and b/web/public/img/impedance_btn.png differ diff --git a/web/public/instructions/res_1.jpg b/web/public/instructions/res_1.jpg index a982c3e7..a9f36a46 100644 Binary files a/web/public/instructions/res_1.jpg and b/web/public/instructions/res_1.jpg differ diff --git a/web/public/instructions/res_2.jpg b/web/public/instructions/res_2.jpg index a1382ee8..1b70a9d6 100644 Binary files a/web/public/instructions/res_2.jpg and b/web/public/instructions/res_2.jpg differ diff --git a/web/public/instructions/res_3.jpg b/web/public/instructions/res_3.jpg index efce7e6a..ef53bae2 100644 Binary files a/web/public/instructions/res_3.jpg and b/web/public/instructions/res_3.jpg differ diff --git a/web/public/instructions/res_4.jpg b/web/public/instructions/res_4.jpg index 5b0153b2..c75131aa 100644 Binary files a/web/public/instructions/res_4.jpg and b/web/public/instructions/res_4.jpg differ diff --git a/web/public/instructions/res_5.jpg b/web/public/instructions/res_5.jpg index 13789b2d..d79274cf 100644 Binary files a/web/public/instructions/res_5.jpg and b/web/public/instructions/res_5.jpg differ diff --git a/web/public/instructions/res_6.jpg b/web/public/instructions/res_6.jpg index bb0bd24e..4fa84b60 100644 Binary files a/web/public/instructions/res_6.jpg and b/web/public/instructions/res_6.jpg differ diff --git a/web/src/components/alternating_text_image.js b/web/src/components/alternating_text_image.js deleted file mode 100644 index 9a78bbb1..00000000 --- a/web/src/components/alternating_text_image.js +++ /dev/null @@ -1,31 +0,0 @@ -import React from 'react'; -import { Row, Col } from 'reactstrap'; - -const AlternatingTextImage = ({ elements }) => - elements.map(({ title, text, image }, i) => { - const textElement = ( - <> -

{title}

-

{text}

- - ); - - const imageElement = {title}; - - return ( -
- {i % 2 === 0 ? ( - - {textElement} - {imageElement} - - ) : ( - - {imageElement} - {textElement} - - )} -
- ); - }); -export default AlternatingTextImage; diff --git a/web/src/components/alternating_text_image/alternating_text_image.js b/web/src/components/alternating_text_image/alternating_text_image.js new file mode 100644 index 00000000..0a488673 --- /dev/null +++ b/web/src/components/alternating_text_image/alternating_text_image.js @@ -0,0 +1,59 @@ +import React from 'react'; +import { Row, Col } from 'reactstrap'; +import { useMediaQuery } from 'react-responsive'; + +import './style.css'; + +const AlternatingTextImage = ({ elements }) => { + const isTabletOrMobile = useMediaQuery({ + query: '(max-width: 1140px)', + }); + + return elements.map(({ title, text, image }, i) => { + const titleElement =

{title}

; + const imageElement = image && ( + {title} + ); + const textElement =

{text}

; + + if (isTabletOrMobile || !image) { + return ( +
+ +
{titleElement}
+ {imageElement} +
{textElement}
+ +
+ ); + } + + return ( +
+ {i % 2 === 0 ? ( + + + {titleElement} + {textElement} + + + {imageElement} + + + ) : ( + + + {imageElement} + + + {titleElement} + {textElement} + + + )} +
+ ); + }); +}; + +export default AlternatingTextImage; diff --git a/web/src/components/alternating_text_image/style.css b/web/src/components/alternating_text_image/style.css new file mode 100644 index 00000000..065bcd4d --- /dev/null +++ b/web/src/components/alternating_text_image/style.css @@ -0,0 +1,20 @@ +.alternating_text_image__img { + max-width: 100%; + min-height: auto; + margin: 0 auto; + padding: 2rem 0; +} + +@media (max-width: 1140px) { + .alternating_text_image__img { + margin: 0 auto; + } +} + +.alternating_text_image__left_img_container { + float: left; +} + +.alternating_text_image__right_img_container { + float: right; +} diff --git a/web/src/components/badge_bullet_point.js b/web/src/components/badge_bullet_point.js new file mode 100644 index 00000000..4aabe2d7 --- /dev/null +++ b/web/src/components/badge_bullet_point.js @@ -0,0 +1,21 @@ +import React from 'react'; +import PropTypes from 'prop-types'; +import { Badge } from 'reactstrap'; + +const BadgeBulletPoint = ({ className, badgeColor, iconClass, children }) => ( +
+ + + +
{children}
+
+); + +BadgeBulletPoint.propTypes = { + className: PropTypes.string, + badgeColor: PropTypes.string, + iconClass: PropTypes.string, + children: PropTypes.any.isRequired, +}; + +export default BadgeBulletPoint; diff --git a/web/src/components/buttons.js b/web/src/components/buttons.js index f4fed526..9b7e5edc 100644 --- a/web/src/components/buttons.js +++ b/web/src/components/buttons.js @@ -18,7 +18,7 @@ export const PreviewButton = ({ block, className, color }) => ( color={color} to={{ pathname: '/sleep-analysis-results', state: { isPreviewMode: true } }} tag={Link} - size="lg" + size="md" > diff --git a/web/src/components/emoji.js b/web/src/components/emoji.js index c1cd87d8..036d8199 100644 --- a/web/src/components/emoji.js +++ b/web/src/components/emoji.js @@ -1,18 +1,20 @@ import React from 'react'; import PropTypes from 'prop-types'; -const Emoji = ({ symbol, label }) => ( - +const Emoji = ({ symbol, label, className }) => ( + {symbol} ); Emoji.propTypes = { symbol: PropTypes.string.isRequired, + className: PropTypes.string, label: PropTypes.string, }; Emoji.defaultProps = { + className: '', label: '', }; diff --git a/web/src/components/floating_card.js b/web/src/components/floating_card.js new file mode 100644 index 00000000..0c57d0d5 --- /dev/null +++ b/web/src/components/floating_card.js @@ -0,0 +1,26 @@ +import React from 'react'; +import PropTypes from 'prop-types'; +import { Card, Col, Row } from 'reactstrap'; + +const FloatingCard = ({ cardClassName, headerText, bodyText, button }) => ( + +
+ + +

{headerText}

+

{bodyText}

+ {button} + +
+
+
+); + +FloatingCard.propTypes = { + cardClassName: PropTypes.string, + headerText: PropTypes.string, + bodyText: PropTypes.any.isRequired, + button: PropTypes.object, +}; + +export default FloatingCard; diff --git a/web/src/components/table.js b/web/src/components/table.js index de31d014..618f4d22 100644 --- a/web/src/components/table.js +++ b/web/src/components/table.js @@ -1,8 +1,8 @@ import React from 'react'; import { Table } from 'reactstrap'; -const SimpleTable = ({ headers, elementsRows }) => ( - +const SimpleTable = ({ headers, elementsrows }) => ( +
{headers.map((header) => ( @@ -11,7 +11,7 @@ const SimpleTable = ({ headers, elementsRows }) => ( - {elementsRows.map((row, i) => ( + {elementsrows.map((row, i) => ( {row.map((element) => ( diff --git a/web/src/views/home/hero/hero.js b/web/src/views/home/hero/hero.js index 1562437a..804ce025 100644 --- a/web/src/views/home/hero/hero.js +++ b/web/src/views/home/hero/hero.js @@ -6,6 +6,7 @@ import HeaderSeparator from 'components/header_separator'; import { RecordMyOwnSleepButton, PreviewButton } from 'components/buttons'; import Logo from 'assets/img/logo.png'; +import PolyCortexFull from 'assets/img/polycortex_full.png'; import './style.css'; @@ -42,12 +43,7 @@ class Hero extends React.Component {
* a project made by - ... + ...
diff --git a/web/src/views/home/sections/call_to_action_section.js b/web/src/views/home/sections/call_to_action_section.js index 0da9ba3e..a763237b 100644 --- a/web/src/views/home/sections/call_to_action_section.js +++ b/web/src/views/home/sections/call_to_action_section.js @@ -1,30 +1,15 @@ import React from 'react'; -import { Card, Col, Container, Row } from 'reactstrap'; +import { Col, Container, Row } from 'reactstrap'; import { RecordMyOwnSleepButton, PreviewButton } from 'components/buttons'; - -import './style.css'; - -const CallToActionCard = ({ cardClassName, headerText, bodyText, button }) => ( - -
- -
-

{headerText}

-

{bodyText}

- {button} - - - - -); +import FloatingCard from 'components/floating_card'; const CallToActionSection = () => (
- ( /> - } + button={} /> diff --git a/web/src/views/home/sections/hardware_section.js b/web/src/views/home/sections/hardware_section.js index 4796ca34..d889aedb 100644 --- a/web/src/views/home/sections/hardware_section.js +++ b/web/src/views/home/sections/hardware_section.js @@ -1,22 +1,8 @@ import React from 'react'; -import { Badge, Col, Container, Row } from 'reactstrap'; +import { Col, Container, Row } from 'reactstrap'; import OpenBCIBoards from 'assets/img/items/boards.png'; - -const PerkItem = ({ iconClass, children }) => ( -
  • -
    -
    - - - -
    -
    -
    {children}
    -
    -
    -
  • -); +import BadgeBulletPoint from 'components/badge_bullet_point'; const HardwareSection = () => (
    @@ -38,9 +24,22 @@ const HardwareSection = () => ( Buy an OpenBCI board
      - Reliable - Cheap and accessible - Open source hardware +
    • + +
      Reliable
      +
      +
    • +
    • + +
      Cheap and accessible
      +
      +
    • + +
    • + +
      Open source hardware
      +
      +
    diff --git a/web/src/views/home/sections/process_section.js b/web/src/views/home/sections/process_section.js index 20c36221..aa579f94 100644 --- a/web/src/views/home/sections/process_section.js +++ b/web/src/views/home/sections/process_section.js @@ -38,8 +38,8 @@ const ProcessSection = () => (

    How It Works?

    - We accompany you through every step of the process from gathering the things you need to exporting your - sleep results. + We accompany you through every step of the process from gathering the things you need to exporting your sleep + results.

    { return ( @@ -25,260 +25,17 @@ const RecordMySleep = () => { subtitle={text['header_subtitle']} description={text['header_description']} /> -
    - -

    - Here are some explanations about how to get your own EEG data in order to score your sleep using this - website. If you already own an OpenBCI board, you could have very little (see nothing) to buy. -

    -

    - If you don’t have the time or the resources to create your own sleep lab, we have pre-recorded one of our - members' night's sleep. You can take a look at the end result right here: -

    -
    -
    - -
    - -

    What you need

    - -
    -
    - -
    - -

    Where to place the electrodes

    -

    - You may want to ask a friend for some help. It will be easier to locate the site where to place your - electrodes and to place them with the help of someone else. -

    -

    - First, you need to know where to place the electrodes. Our channels are Fpz-Cz and Pz-Oz to which we add a - driven ground electrode placed at A2 (on your right ear lobe). -

    - -
    -
    - -
    - -

    How to place the electrodes

    - -
    -

    Apply Abrasive paste

    -

    - Now that you marked all these locations, you can clean the areas with abrasive paste. Exfoliate the skin - with a cotton swab until it begins to turn pink, and then wash the skin using some rubbing alcohol and a - cotton pad. -

    -
    - -
    -

    Place your electrodes

    -

    Make sure your electrodes are clean.

    -

    - For Cz, Pz and Oz (electrodes placed over your scalp): Squeeze some EC2 over a gauze pad, take an - electrode and apply a good amount of Ten20 paste into the cup, and then set the electrode down on the EC2. - Finally, take the gauze pad with the electrode and place it on the marked area. -

    -

    - For Fpz and A2 (electrodes directly placed over skin): Apply a good amount of Ten20 paste into the - cup, place it on the marked area and fix it with a small cutoff of Hypafix. If you do not have Ten20 - paste, just use EC2 paste as above. -

    -

    - Please note: A good amount of Ten20 paste means filling the cup until it slightly overflows with paste. -

    - -
    - Electrodes in Ten20 - - - EC2 on gauze - - - Electrodes on gauze - - - - -
    -

    Wire the electrodes to the OpenBCI device

    -

    Here’s is how you need to wire your electrodes to the OpenBCI board you are using:

    -
    {element}
    - - - - -
    - - - - -
    Ensure good skin contact
    -

    - To ensure that skin contact is good, it is important to measure the impedance between the electrodes. - Start by measuring the impedance between your active electrode and its reference (e.g.: Fpz and Cz). - Also, check the impedance between the reference electrodes of each channel (Cz and Oz) and the ground - electrode (A2). As a rule of thumb, low impedance (10 KOhms) is good and high ones are bad (let’s say - 150 KOhms). -

    -
    -
    - - -
    Limit noise
    -

    - Tie the electrodes together with a hair tie, and if you have long hair, tie them all together in order - to avoid static during the night. To limit electromagnetic interferences you may want to place your - board in some sort of Faraday cage, for example, a plastic container wrapped up in aluminium foil. -

    -
    -
    -
    -
    -
    - -
    - -

    How to use OpenBCI GUI

    -

    - First thing you need is the OpenBCI GUI in order to use the hardware. Therefrom, select{' '} - Live (from <boardname>) as your source. If you’re using a Cyton board we suggest you use a - microSD card using FAT32 format. If you do so, do not forget to select at least 12 hour maximum for - the write to SD card parameter. Otherwise, you must keep your computer near and open for the whole night and - log the data to a session file. If you do it this way, do not forget to select the OpenBCI file output and - to select No Limit as your max file duration. When everything is configured properly, you can press{' '} - Start Session. Before pressing Start Stream, press Hardware Settings and configure - everything as follow: -

    - - -
    -

    Cyton

    -
    - - -

    Ganglion

    -
    - - - -

    - Do not forget to deactivate all unused channels by greying out the numbered colored pill on the left of the - signal in the GUI. You can now press Start data stream. If you are using a microSD card and a Cyton - board, you may want to pull off the dongle from its usb port. Data will be written to the SD card for the - configured amount of time. -

    - - - -
    - -

    Write a journal

    -

    - You must keep a journal (accurate to the minute) and write down a few information to help us track and - analyze your sleep: -

    -

    - - - - When you start the stream -

    -

    - - - - When you go to bed -

    -

    - - - - When you wake up -

    -

    You will need to provide this information in order to score your EEG recording.

    -
    -
    - -
    - -

    Wake up!

    -
    -

    Remove your electrodes

    -

    - In order to take the electrodes off your scalp, you can use warm water for the EC2 to come off easily. The - Hypafix, used for electrodes over the skin, should be taken off with warm water and/or rubbing alcohol. - Prefer taking them off slowly, since they can hurt sensible skin if removed too quickly. Don’t forget to - clean your electrodes using warm water and soap. -

    -
    -
    -

    If you used an microSD card:

    -

    - Remove the microSD card from the board and insert it in your computer. Then, open OpenBCI GUI and select{' '} - PLAYBACK (from file) as your data source. Use the Convert SD for playback option and select - your sd file. Wait a little bit and you will get the converted csv file. Upload this one to this website - in order to score your sleep -

    -
    -
    -

    If you used session file:

    -

    - After stopping the stream, go to the Recordings directory where your session file. Just upload this file - in order to score your sleep and analyze your data. -

    -
    -
    -
    - -
    - -

    How we did it

    - -
    -

    - Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et - dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip - ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu - fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia - deserunt mollit anim id est laborum. -

    - - -
    - - - - - + + + + + + + + + + + ); }; diff --git a/web/src/views/record_my_sleep/material_needed.json b/web/src/views/record_my_sleep/material_needed.json deleted file mode 100644 index c9fef318..00000000 --- a/web/src/views/record_my_sleep/material_needed.json +++ /dev/null @@ -1,59 +0,0 @@ -{ - "elements": [ - { "title": "Some cotton swabs", "text": "We use them to apply the abrasive paste on the skin.", "image": "" }, - { "title": "Medical tape", "text": "It’s your Flex Tape!", "image": "illustrations/medical_tape.png" }, - { "title": "Rubbing alcohol", "text": "Disinfect skin", "image": "" }, - { - "title": "Hypafix", - "text": "Hypafix is useful to fix electrodes directly to your skin, and holds on better than EC2. In our case, it would be used for the Fpz on the forehead and for the driven ground electrode on the earlobe.", - "image": "illustrations/hypafix.png" - }, - { - "title": "Square gauze pads", - "text": "Place it over the electrodes and EC2 paste", - "image": "illustrations/gauze_pads.png" - }, - { - "title": "Abrasive paste (Nuprep skin prep gel)", - "text": "Gets rid of dead skin and improves electrodes conductivity.", - "image": "illustrations/prep_gel.png" - }, - { "title": "4 AA batteries", "text": "To power your board", "image": "" }, - { - "title": "An OpenBCI board (Cyton or Ganglion) with its dongle", - "text": "We’re using two channels and a driven ground.", - "image": "illustrations/chip.png" - }, - { - "title": "Gold cup electrodes", - "text": "This type of electrodes is easy to find and works great for sleep EEG recording", - "image": "illustrations/electrode.png" - }, - { - "title": "A micro SD card (for Cyton users)", - "text": "OpenBCI boards do not work with every kind of microSD card. We tested a SanDisk Ultra 32Gb and Kingston SDHC 8Gb class 4 for our recordings.", - "image": "illustrations/sd.png" - }, - { - "title": "Something to attach the board to your body", - "text": "So you can move around without having to keep the OpenBCI board in your hands (e.g.: we used a camera bag and a fanny pack)", - "image": "" - }, - { - "title": "A flexible measuring tape", - "text": "To place the electrodes in the right places.", - "image": "illustrations/measuring_tape.png" - }, - { - "title": "EC2 conductive paste", - "text": "We highly recommend you to use EC2 paste, because it sticks the electrodes really well to your skin, even when applied through hair. It can also be easily washed off afterwards.", - "image": "illustrations/ec2.png" - }, - { - "title": "Ten20 conductive paste (alternative)", - "text": "Ten20 can be a viable solution if you can manage to keep your electrodes in place for the whole night (via medical tape and/or a headband). You can also use both at the same time.", - "image": "illustrations/ten20.png" - }, - { "title": "Easily erasable pencil", "text": "To mark where electrodes should go", "image": "" } - ] -} diff --git a/web/src/views/record_my_sleep/sections/call_to_action/index.js b/web/src/views/record_my_sleep/sections/call_to_action/index.js new file mode 100644 index 00000000..72854042 --- /dev/null +++ b/web/src/views/record_my_sleep/sections/call_to_action/index.js @@ -0,0 +1,24 @@ +import React from 'react'; +import { Link } from 'react-router-dom'; +import { Button, Container } from 'reactstrap'; + +const CallToAction = () => ( +
    + +

    Analyze my sleep

    +

    + Now that you have your recorded sleep data file, you will need to install and run the sleep analysis server. + Then, you will be able to submit your recorded data to the Polydodo sleep analysis algorithm. When you are ready + to proceed, perhaps after a sip of coffee, it's right there: +

    + +
    +
    +); + +export default CallToAction; diff --git a/web/src/views/record_my_sleep/sections/connections_section/index.js b/web/src/views/record_my_sleep/sections/connections_section/index.js new file mode 100644 index 00000000..26abfce3 --- /dev/null +++ b/web/src/views/record_my_sleep/sections/connections_section/index.js @@ -0,0 +1,52 @@ +import React from 'react'; +import { Col, Container, Row } from 'reactstrap'; + +import Table from 'components/table'; + +import './style.css'; + +const ConnectionsSection = () => ( +
    + +
    +

    Connect the electrodes

    +

    Here is how you need to connect your electrodes to the OpenBCI board you are using:

    + +
    + + + + + + +

    Connections table for each electrode

    +
    +

    + The headers pins of the electrodes can be disconnected rather easily. Make sure that no pressure is exerted on + the wire at any time. On our side, we decided to tap the wire on its container, in order to avoid such a + scenario. It is now time to power your OpenBCI device. We suggest full charged batteries, since the device + will be powered on for several hours. +

    + + + +); + +export default ConnectionsSection; diff --git a/web/src/views/record_my_sleep/sections/connections_section/style.css b/web/src/views/record_my_sleep/sections/connections_section/style.css new file mode 100644 index 00000000..9235f84e --- /dev/null +++ b/web/src/views/record_my_sleep/sections/connections_section/style.css @@ -0,0 +1,4 @@ +.connections_section__connections_img { + max-width: 35rem; + margin-bottom: 3rem; +} diff --git a/web/src/views/record_my_sleep/sections/electrodes_application_section/index.js b/web/src/views/record_my_sleep/sections/electrodes_application_section/index.js new file mode 100644 index 00000000..28bddf50 --- /dev/null +++ b/web/src/views/record_my_sleep/sections/electrodes_application_section/index.js @@ -0,0 +1,100 @@ +import React from 'react'; +import { Col, Container, Row } from 'reactstrap'; + +import HeaderSeparator from 'components/header_separator'; + +import './style.css'; + +const Step = ({ imgElement, titlePrefix, title, description }) => ( +
    + +

    + {titlePrefix} + {title} +

    +
    + + {imgElement} + + +
    + {description} + + + +); + +const ElectrodesApplicationSection = () => ( +
    +
    + + + + + + + + + + +
    {' '} + +

    How to place the electrodes

    + +
    +

    Apply skin preparation gel

    +

    + Pour a small amount of abrasive paste where your Fpz mark is and exfoliate the skin with a cotton swab until + it begins to turn pink. Using rubbing alcohol and a cotton swab, wipe away the skin several times in order to + remove dead skin. Repeat this for all marked locations. +

    +
    + +
    +

    Place the scalp electrodes (Cz, Pz and Oz)

    +

    + First, make sure your electrodes are clean. For more info on how to wash them, see the Wake Up section below. + Then, follow these three steps: +

    + + + } + description="Apply a good amount of Ten20 paste into the cup. This means filling the cup until it slightly overflows with paste." + /> + } + description="Squeeze some EC2 conductive paste on a gauze pad. Ensure there's enough so that it will surround the electrode." + /> + + } + description="Set the electrode down on the EC2. Place the concave side towards the outside of the fabric." + /> + +

    + Finally, take the gauze pad with the electrode and the EC2 and place it on the marked area. Exerce a small + pressure on the gauze square with your palm. The electrode should stay in place. The EC2 conductive paste + should take a couple minutes to dry (try to avoid sudden movements). Repeat these steps for the two others + scalp electrodes. +

    +

    Place the skin electrodes (Fpz and A2)

    +

    + As with the scalp electrodes' first step, fill the electrode cup with a good amount of Ten20. Afterwards, + cutoff a small piece of Hypafix. Place the electrode over the mark and apply the Hypafix medical tape tightly. + The electrode should be secured under the tape. +

    +
    +
    + +
    +); +export default ElectrodesApplicationSection; diff --git a/web/src/views/record_my_sleep/sections/electrodes_application_section/style.css b/web/src/views/record_my_sleep/sections/electrodes_application_section/style.css new file mode 100644 index 00000000..621ba1e5 --- /dev/null +++ b/web/src/views/record_my_sleep/sections/electrodes_application_section/style.css @@ -0,0 +1,9 @@ +.electrodes_application_section__step_image { + min-height: 12rem; +} + +@media (min-width: 992px) { + .electrodes_application__section { + margin-bottom: 20rem; + } +} diff --git a/web/src/views/record_my_sleep/electrodes_display.js b/web/src/views/record_my_sleep/sections/electrodes_placement_section/electrodes_display.js similarity index 50% rename from web/src/views/record_my_sleep/electrodes_display.js rename to web/src/views/record_my_sleep/sections/electrodes_placement_section/electrodes_display.js index 9f963987..0e032afb 100644 --- a/web/src/views/record_my_sleep/electrodes_display.js +++ b/web/src/views/record_my_sleep/sections/electrodes_placement_section/electrodes_display.js @@ -3,58 +3,51 @@ import { Row, Col } from 'reactstrap'; import Tabs from 'components/tabs'; -import './electrode_display.css'; +import './style.css'; -const ElectrodesDisplay = () => { +const ElectrodesDisplay = ({ className }) => { const [selectedElectrode, setSelectedElectrode] = useState('fpz'); return ( - -
    + + - +
    top diff --git a/web/src/views/record_my_sleep/sections/electrodes_placement_section/index.js b/web/src/views/record_my_sleep/sections/electrodes_placement_section/index.js new file mode 100644 index 00000000..3ac45d6d --- /dev/null +++ b/web/src/views/record_my_sleep/sections/electrodes_placement_section/index.js @@ -0,0 +1,68 @@ +import BadgeBulletPoint from 'components/badge_bullet_point'; +import React from 'react'; +import { Alert, Container } from 'reactstrap'; + +import ElectrodesDisplay from './electrodes_display'; + +const ElectrodesPlacementSection = () => ( +
    + + + + + For the two next parts, you may want to ask a friend for some help. It will be far easier in + order to locate and fix each electrode. + + +

    Where to place the electrodes

    +

    + First, you need to know where to place the electrodes. You will need the soft tape measure to measure the head + according to the 10-20 placement system and then you will mark as precisely as possible each electrode's + location using a marker. The montage is composed of the Fpz-Cz and Pz-Oz channels to which we add a driven + ground electrode placed at A2. This montage is based on an alternative electrode placement for sleep analysis + [Sweden, Kemp, Kamphuisen and Velde, 1990]. +

    +
    +
      +
    • + +
      + First, you will need to measure the distance starting from your  + + nasion + +  to your  + + inion. + +
      +
      +
    • +
    • + +
      + Then, using this measure, follow the table below to get some detailed explanations on where to draw + marks for each location. +
      +
      +
    • +
    +
    + + + +
    + [Sweden, Kemp, Kamphuisen and Velde, 1990] B. V. Sweden, B. Kemp, H. A. C. Kamphuisen, and E.A.V.D. Velde. + Alternative Electrode Placement in (Automatic) Sleep Scoring (Fpz-Cz/Pz-Oz versus C4-At). Sleep, + 13(3):279–283, 1990. +
    +
    +
    +
    +); + +export default ElectrodesPlacementSection; diff --git a/web/src/views/record_my_sleep/electrode_display.css b/web/src/views/record_my_sleep/sections/electrodes_placement_section/style.css similarity index 96% rename from web/src/views/record_my_sleep/electrode_display.css rename to web/src/views/record_my_sleep/sections/electrodes_placement_section/style.css index ffadeefe..cdb42e46 100644 --- a/web/src/views/record_my_sleep/electrode_display.css +++ b/web/src/views/record_my_sleep/sections/electrodes_placement_section/style.css @@ -20,7 +20,7 @@ } .dot-select { - background-color: #fc7c5f; + background-color: #5e72e4; } .dot-null { diff --git a/web/src/views/record_my_sleep/sections/gui_configuration_section/index.js b/web/src/views/record_my_sleep/sections/gui_configuration_section/index.js new file mode 100644 index 00000000..af674ba2 --- /dev/null +++ b/web/src/views/record_my_sleep/sections/gui_configuration_section/index.js @@ -0,0 +1,67 @@ +import React from 'react'; +import { Alert, Col, Container, Row } from 'reactstrap'; +import Table from 'components/table'; + +const GUIConfigurationSection = () => ( +
    + +

    How to use OpenBCI GUI

    +

    + First thing you need is the  + + + OpenBCI GUI + + +  in order to use the hardware. Therefrom, select Live (from <boardname>) as your source. If + you’re using a Cyton board we suggest you use a microSD card using FAT32 format. If you do so, do not forget to + select at least  + 12 hour maximum for the write to SD card parameter. +

    + + + + Despite the fact that the Ganglion has a slot to receive a microsd card, it cannot be used. +  This was a bonus feature to their Kickstarter campaign, but eventually the feature has been put aside. + + +

    + Otherwise, you must keep your computer near and open for the whole night and log the data to a session file. If + you do it this way, do not forget to select the OpenBCI file output and to select  + No Limit as your max file duration. When everything is configured properly, you can press  + Start Session. Before pressing Start Stream, press Hardware Settings and configure + everything as follow: +

    + +
    +

    Cyton

    +
    + + +

    Ganglion

    +
    + + +

    + Do not forget to deactivate all unused channels by greying out the numbered colored pill on the left of the + signal in the GUI. You can now press Start data stream. If you are using a microSD card and a Cyton + board, you may want to pull off the dongle from its usb port. Data will be written to the SD card for the + configured amount of time. +

    + + +); + +export default GUIConfigurationSection; diff --git a/web/src/views/record_my_sleep/carousel_images.json b/web/src/views/record_my_sleep/sections/how_we_did_section/carousel_images.json similarity index 67% rename from web/src/views/record_my_sleep/carousel_images.json rename to web/src/views/record_my_sleep/sections/how_we_did_section/carousel_images.json index d4e203da..bc1d04cc 100644 --- a/web/src/views/record_my_sleep/carousel_images.json +++ b/web/src/views/record_my_sleep/sections/how_we_did_section/carousel_images.json @@ -3,32 +3,38 @@ { "src": "instructions/res_1.jpg", "altText": "Slide 1", - "caption": "1" + "caption": "", + "header": "" }, { "src": "instructions/res_2.jpg", "altText": "Slide 2", - "caption": "2" + "caption": "", + "header": "" }, { "src": "instructions/res_3.jpg", "altText": "Slide 3", - "caption": "3" + "caption": "", + "header": "" }, { "src": "instructions/res_4.jpg", "altText": "Slide 4", - "caption": "4" + "caption": "", + "header": "" }, { "src": "instructions/res_5.jpg", "altText": "Slide 5", - "caption": "5" + "caption": "", + "header": "" }, { "src": "instructions/res_6.jpg", "altText": "Slide 6", - "caption": "6" + "caption": "", + "header": "" } ] } diff --git a/web/src/views/record_my_sleep/sections/how_we_did_section/index.js b/web/src/views/record_my_sleep/sections/how_we_did_section/index.js new file mode 100644 index 00000000..91ac5aad --- /dev/null +++ b/web/src/views/record_my_sleep/sections/how_we_did_section/index.js @@ -0,0 +1,52 @@ +import React from 'react'; +import { UncontrolledCarousel, Col, Container, Row } from 'reactstrap'; +import _ from 'lodash'; + +import HeaderSeparator from 'components/header_separator'; + +import carouselImages from './carousel_images.json'; + +const HowWeDidSection = () => ( +
    +
    + + + + + + +
    + + + +
    +

    How we did it

    + +

    + On these photos, we can clearly see the application of the electrodes. Please ignore the electrodes placed + at chin and eye level (they were used for manual data scoring purposes). For this recording, we used the + Cyton board and a microSD card. We put the board in a disposable plastic container that we covered with + aluminum foil, to limit EMIs. Then, we put the container in a camera bag worn with a shoulder strap to be + able to carry the board on us. +

    + +
    +
    + + Object({ + ...item, + src: `${process.env.PUBLIC_URL}/${item.src}`, + }), + )} + /> +
    + + + + + +); + +export default HowWeDidSection; diff --git a/web/src/views/record_my_sleep/sections/introduction_section/index.js b/web/src/views/record_my_sleep/sections/introduction_section/index.js new file mode 100644 index 00000000..7c83c61a --- /dev/null +++ b/web/src/views/record_my_sleep/sections/introduction_section/index.js @@ -0,0 +1,40 @@ +import React from 'react'; +import { Card, Col, Container, Row } from 'reactstrap'; + +import { PreviewButton } from 'components/buttons'; + +import './style.css'; + +const IntroductionSection = () => ( +
    + +

    + Here is a comprehensive guide that explains how to record your own EEG data with an OpenBCI board. The proposed + method ensures that the recorded data will be compatible with Polydodo. This guide presents the list of needed + materials, the positioning of the electrodes, their placement, as well as their connection. After, it will focus + on configuring the OpenBCI boards and on what to do overnight. Be sure to follow our tips and tricks on how to + maintain a good signal to noise ratio. Note that the supplies and the application methods are meant to follow + best practices and to provide good quality data. +

    +
    + +
    + +
    +

    Not sure yet?

    +

    + If you'd first like to see what the sleep analysis looks like, check out the preview. +

    + +
    + + + + + + + + +); + +export default IntroductionSection; diff --git a/web/src/views/record_my_sleep/sections/introduction_section/style.css b/web/src/views/record_my_sleep/sections/introduction_section/style.css new file mode 100644 index 00000000..05f3cb63 --- /dev/null +++ b/web/src/views/record_my_sleep/sections/introduction_section/style.css @@ -0,0 +1,3 @@ +.introduction_section__preview_card { + padding: 2rem; +} diff --git a/web/src/views/record_my_sleep/sections/journal_section/index.js b/web/src/views/record_my_sleep/sections/journal_section/index.js new file mode 100644 index 00000000..d81afdbe --- /dev/null +++ b/web/src/views/record_my_sleep/sections/journal_section/index.js @@ -0,0 +1,42 @@ +import React from 'react'; +import { Container } from 'reactstrap'; + +import BadgeBulletPoint from 'components/badge_bullet_point'; + +const JournalSection = () => ( +
    + +

    + Write a journal +

    +

    + During the night, you must keep a journal, accurate to the minute, and write down a few information to help us + track and analyze your sleep: +

    +
      +
    • + + When you start the stream + +
    • +
    • + + When you go to bed + +
    • +
    • + + When you get out of bed + +
    • +
    +

    This information must be given when filling out the upload form for your EEG data file.

    +

    + + Good night! +

    +
    +
    +); + +export default JournalSection; diff --git a/web/src/views/record_my_sleep/sections/material_section/index.js b/web/src/views/record_my_sleep/sections/material_section/index.js new file mode 100644 index 00000000..d4178f1d --- /dev/null +++ b/web/src/views/record_my_sleep/sections/material_section/index.js @@ -0,0 +1,22 @@ +import React from 'react'; +import { Container } from 'reactstrap'; + +import AlternatingTextImage from 'components/alternating_text_image/alternating_text_image'; + +import materialNeeded from './material_needed.json'; + +const MaterialSection = () => ( +
    + +

    What you will need

    +

    + If you already own an OpenBCI board and some basic EEG equipment, you could have very little to buy except a few + things from the drugstore. Some of the brands that we mention have their equivalent and can be replaced. We do + not advertise the mentionned products, but we have used them and found them useful and of good quality. +

    + +
    +
    +); + +export default MaterialSection; diff --git a/web/src/views/record_my_sleep/sections/material_section/material_needed.json b/web/src/views/record_my_sleep/sections/material_section/material_needed.json new file mode 100644 index 00000000..b83e36b8 --- /dev/null +++ b/web/src/views/record_my_sleep/sections/material_section/material_needed.json @@ -0,0 +1,44 @@ +{ + "elements": [ + { + "title": "Rubbing alcohol, cotton swabs and medical tape", + "text": "Rubbing alcohol is important for disinfecting the skin. Cotton swabs will be used to apply different products to the skin. Medical tape is optional, but helpful to hold certain electrodes on the skin which could come off. If you don't already have these, you can find them all at the drugstore for cheap.", + "image": "illustrations/alcohol__cotton_swabs__medical_tape.png" + }, + { + "title": "Hypafix and gauze squares", + "text": "Hypafix is a skin adhesive that holds very well in place while being stretchy and comfortable. This can seem a little bit expensive, but it is really useful to keep the electrodes in place for the long term such as a whole night. While we recommend it, you can also use medical tape to replace the Hypafix, but it is less suitable for long term recordings like sleep study. You will also need pieces of gauze wrap (or gauze pads) to receive and to isolate the conductive paste. You will be able to get Hypafix from medical equipment distributors and gauze wrap can be found at your local drugstore.", + "image": "illustrations/hypafix__gauze_wrap.png" + }, + { + "title": "Abrasive paste for skin preparation", + "text": "Skin prep gel gets rid of dead skin and other impurities when applied to skin. It lowers the connection's impedance and increases conductivity. Concretly, it helps a lot to reduce the signal's noise. We are using NuPrep Skin Gel Prep, but like we already mentionned, multiple equivalent brands are available. You may find it online from different medical equipment distributors.", + "image": "illustrations/prep_gel.png" + }, + { + "title": "EC2 and Ten20 conductive paste", + "text": "Conductive paste is an essential part of the montage, because it ensures a good electrical contact between the skin and the electrodes. EC2 is a special conductive paste because it is also a very good adhesive. It comes really handy when applying electrodes to the scalp. Indeed, it holds the electrodes in place all night, even with thick hair, and can be washed off easily afterwards. Ten20 is used for its excellent conductive properties. You can easily find them online along with their equivalent brands.", + "image": "illustrations/ec2_ten20.png" + }, + { + "title": "An OpenBCI board (Cyton or Ganglion) with its dongle, 5 Gold Cup Electrodes and 4 AA batteries", + "text": "OpenBCI boards are low-cost brain-computer interface hardware that provides high quality biosignals. We’re using two channels and a driven ground to record the EEG activity while sleeping. Polydodo is compatible with both Cyton and Ganglion boards. To use them, you will also need the OpenBCI GUI to configure and monitor your recordings. Goldcup electrodes works great for sleep EEG recording and are easy to find. You can find the boards and the electrode on the official OpenBCI store. You'll also need 4 full-charged AA batteries to power the board for the whole night.", + "image": "illustrations/open_bci__electrodes__batteries.png" + }, + { + "title": "A micro SD card (for Cyton users only)", + "text": "If you have a Cyton board, you will probably want to use a SD card. It makes recordings more convenient because it removes the need to maintain the connection between your board and your computer. If you choose to use one, please note that Cyton boards do not work with every kind of microSD card. We can only approve the one we tested: SanDisk Ultra 32Gb class 10 and Kingston SDHC 8Gb class 4. Some other brands we tested were not compatible at all like the Lexar 633x 32gb class 10. Refer to the OpenBCI SD card documentation for more information. That's why we recommend to stick to these.", + "image": "illustrations/sd.png" + }, + { + "title": "A soft tape measure and an easily erasable marker", + "text": "The measuring tape is used to measure the head and the marker to make a mark at the electrodes' spots.", + "image": "illustrations/pen_tape.png" + }, + { + "title": "Something to attach the board to your body", + "text": "You'll need something to put your OpenBCI board in, so you can move around without having to carry the board in your hands. Also, electrode wires can be very short, and thus it makes it useful to secure the board near your chest. We used a camera bag and a fanny pack, but any small bag will do.", + "image": "" + } + ] +} diff --git a/web/src/views/record_my_sleep/sections/tips_and_tricks_section/index.js b/web/src/views/record_my_sleep/sections/tips_and_tricks_section/index.js new file mode 100644 index 00000000..c6305903 --- /dev/null +++ b/web/src/views/record_my_sleep/sections/tips_and_tricks_section/index.js @@ -0,0 +1,64 @@ +import React from 'react'; +import { CardDeck, Col, Container, UncontrolledTooltip } from 'reactstrap'; + +import FloatingCard from 'components/floating_card'; + +import './style.css'; + +const TipsAndTricksSection = () => ( +
    + + +
    + + To confirm that skin contact is good, it is important to measure the impedance between the electrodes. + You can check the impedance between your active electrode and its reference (e.g.: Fpz and Cz) through + the OpenBCI GUI. The  + + + impedance button + + + + + +  appears just beside the channel number. As a rule of thumb, low impedance (like 10 KOhms) is good + and high ones are bad (such as 150 KOhms). + + } + /> + + + + To limit electromagnetic interferences, there are various techniques.  + + + Twisting pairs of electrodes' wires together + + + , and placing the board in some sort of Faraday cage (like aluminium foil, but be sure the board is + isolated from the foil!) can be effective. If you have long hair, tie them all together in order to + avoid static electricity during the night. + + } + /> + + + + +); + +export default TipsAndTricksSection; diff --git a/web/src/views/record_my_sleep/sections/tips_and_tricks_section/style.css b/web/src/views/record_my_sleep/sections/tips_and_tricks_section/style.css new file mode 100644 index 00000000..97fd0e6d --- /dev/null +++ b/web/src/views/record_my_sleep/sections/tips_and_tricks_section/style.css @@ -0,0 +1,4 @@ +.tooltip-inner { + max-width: 100%; + padding: 1rem; +} diff --git a/web/src/views/record_my_sleep/sections/wake_up_section/index.js b/web/src/views/record_my_sleep/sections/wake_up_section/index.js new file mode 100644 index 00000000..54933be3 --- /dev/null +++ b/web/src/views/record_my_sleep/sections/wake_up_section/index.js @@ -0,0 +1,31 @@ +import React from 'react'; +import { Container } from 'reactstrap'; + +const WakeUpSection = () => ( +
    + +

    + Wake up! +

    +
    +

    Remove & clean your electrodes

    +

    + In order to take the electrodes off your scalp, you can use warm water for the EC2 to come off easily. The + Hypafix, used for electrodes over the skin, should be taken off with warm water and/or rubbing alcohol. Prefer + taking them off slowly, since they can hurt sensible skin if removed too quickly. Don’t forget to clean your + electrodes. To do this, you can fill a sink with hot water and soap, then use cotton swabs to remove the paste + from the electrodes. Do not leave the electrodes in hot water for too long, as this may damage them. Dry them. +

    +
    +
    +

    Retrieve your recording

    +

    + If you used a microSD card, remove it from the board and insert it in your computer. If you used the session + file way, after stopping the stream, go to the Recordings directory where should be stored your session file. +

    +
    +
    +
    +); + +export default WakeUpSection; diff --git a/web/src/views/record_my_sleep/text.json b/web/src/views/record_my_sleep/text.json index d176dded..592cba78 100644 --- a/web/src/views/record_my_sleep/text.json +++ b/web/src/views/record_my_sleep/text.json @@ -1,5 +1,5 @@ { "header_title": "Create your own sleep lab", - "header_subtitle": "at home, using a little.", - "header_description": "" + "header_subtitle": "at home, using a little", + "header_description": "Learn how to record your own EEG data using an OpenBCI board" } diff --git a/web/yarn.lock b/web/yarn.lock index c2e315fd..53e54e09 100644 --- a/web/yarn.lock +++ b/web/yarn.lock @@ -3606,6 +3606,11 @@ css-loader@4.3.0: schema-utils "^2.7.1" semver "^7.3.2" +css-mediaquery@^0.1.2: + version "0.1.2" + resolved "https://registry.yarnpkg.com/css-mediaquery/-/css-mediaquery-0.1.2.tgz#6a2c37344928618631c54bd33cedd301da18bea0" + integrity sha1-aiw3NEkoYYYxxUvTPO3TAdoYvqA= + css-prefers-color-scheme@^3.1.1: version "3.1.1" resolved "https://registry.yarnpkg.com/css-prefers-color-scheme/-/css-prefers-color-scheme-3.1.1.tgz#6f830a2714199d4f0d0d0bb8a27916ed65cff1f4" @@ -5882,6 +5887,11 @@ human-signals@^1.1.1: resolved "https://registry.yarnpkg.com/human-signals/-/human-signals-1.1.1.tgz#c5b1cd14f50aeae09ab6c59fe63ba3395fe4dfa3" integrity sha512-SEQu7vl8KjNL2eoGBLF3+wAjpsNfA9XMlXAYj/3EdaNfAlxKthD1xjEQfGOUhllCGGJVNY34bRr6lPINhNjyZw== +hyphenate-style-name@^1.0.0: + version "1.0.4" + resolved "https://registry.yarnpkg.com/hyphenate-style-name/-/hyphenate-style-name-1.0.4.tgz#691879af8e220aea5750e8827db4ef62a54e361d" + integrity sha512-ygGZLjmXfPHj+ZWh6LwbC37l43MhfztxetbFCoYTM2VjkIUpeHgSNn7QIyVFj7YQ1Wl9Cbw5sholVJPzWvC2MQ== + iconv-lite@0.4, iconv-lite@0.4.24, iconv-lite@^0.4.24: version "0.4.24" resolved "https://registry.yarnpkg.com/iconv-lite/-/iconv-lite-0.4.24.tgz#2022b4b25fbddc21d2f524974a474aafe733908b" @@ -7341,6 +7351,13 @@ map-visit@^1.0.0: dependencies: object-visit "^1.0.0" +matchmediaquery@^0.3.0: + version "0.3.1" + resolved "https://registry.yarnpkg.com/matchmediaquery/-/matchmediaquery-0.3.1.tgz#8247edc47e499ebb7c58f62a9ff9ccf5b815c6d7" + integrity sha512-Hlk20WQHRIm9EE9luN1kjRjYXAQToHOIAHPJn9buxBwuhfTHoKUcX+lXBbxc85DVQfXYbEQ4HcwQdd128E3qHQ== + dependencies: + css-mediaquery "^0.1.2" + md5.js@^1.3.4: version "1.3.5" resolved "https://registry.yarnpkg.com/md5.js/-/md5.js-1.3.5.tgz#b5d07b8e3216e3e27cd728d72f70d1e6a342005f" @@ -9391,6 +9408,16 @@ react-refresh@^0.8.3: resolved "https://registry.yarnpkg.com/react-refresh/-/react-refresh-0.8.3.tgz#721d4657672d400c5e3c75d063c4a85fb2d5d68f" integrity sha512-X8jZHc7nCMjaCqoU+V2I0cOhNW+QMBwSUkeXnTi8IPe6zaRWfn60ZzvFDZqWPfmSJfjub7dDW1SP0jaHWLu/hg== +react-responsive@^8.1.1: + version "8.1.1" + resolved "https://registry.yarnpkg.com/react-responsive/-/react-responsive-8.1.1.tgz#e4b1bd677798deecb4f1c3cff35a020ca0abdb27" + integrity sha512-kvgOGU4m64ALsDiNKgImW6xtbdx/aSuw8sTCHC8RsBlkXsDA/gMoZkYboZuk4V9DhX6bCFh4gBH2UqlYVPLvcA== + dependencies: + hyphenate-style-name "^1.0.0" + matchmediaquery "^0.3.0" + prop-types "^15.6.1" + shallow-equal "^1.1.0" + react-router-dom@^5.2.0: version "5.2.0" resolved "https://registry.yarnpkg.com/react-router-dom/-/react-router-dom-5.2.0.tgz#9e65a4d0c45e13289e66c7b17c7e175d0ea15662" @@ -10221,6 +10248,11 @@ shallow-clone@^3.0.0: dependencies: kind-of "^6.0.2" +shallow-equal@^1.1.0: + version "1.2.1" + resolved "https://registry.yarnpkg.com/shallow-equal/-/shallow-equal-1.2.1.tgz#4c16abfa56043aa20d050324efa68940b0da79da" + integrity sha512-S4vJDjHHMBaiZuT9NPb616CSmLf618jawtv3sufLl6ivK8WocjAo58cXwbRV1cgqxH0Qbv+iUt6m05eqEa2IRA== + shebang-command@^1.2.0: version "1.2.0" resolved "https://registry.yarnpkg.com/shebang-command/-/shebang-command-1.2.0.tgz#44aac65b695b03398968c39f363fee5deafdf1ea"