aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--.babelrc3
-rw-r--r--.bowerrc3
-rw-r--r--.eslintrc.js4
-rw-r--r--.vscode/launch.json22
-rw-r--r--.vscode/tasks.json15
-rw-r--r--bower.json22
-rw-r--r--package.json17
-rw-r--r--src/client/react/components/container/HelpBox.js4
-rw-r--r--src/client/react/components/container/HelpBox.scss23
-rw-r--r--src/client/react/components/container/Menu.js30
-rw-r--r--src/client/react/components/container/Menu.scss25
-rw-r--r--src/client/react/components/container/Results.js6
-rw-r--r--src/client/react/components/container/Results.scss5
-rw-r--r--src/client/react/components/container/RoomFinder.js12
-rw-r--r--src/client/react/components/container/RoomFinder.scss23
-rw-r--r--src/client/react/components/container/Search.js12
-rw-r--r--src/client/react/components/container/Search.scss42
-rw-r--r--src/client/react/components/container/WeekSelector.js4
-rw-r--r--src/client/react/components/container/WeekSelector.scss40
-rw-r--r--src/client/react/components/page/Index.js4
-rw-r--r--src/client/react/components/page/Index.scss33
-rw-r--r--src/client/react/components/page/User.js12
-rw-r--r--src/client/react/components/page/User.scss24
-rw-r--r--src/client/react/components/presentational/Loading.js2
-rw-r--r--src/client/react/components/presentational/Loading.scss5
-rw-r--r--src/client/react/components/presentational/Result.js15
-rw-r--r--src/client/react/components/presentational/Result.scss30
-rw-r--r--src/client/react/index.js21
-rw-r--r--src/client/react/index.scss12
-rw-r--r--src/client/static/browserconfig.xml2
-rw-r--r--src/client/static/icons/apple-touch-icon.png (renamed from src/client/static/apple-touch-icon.png)bin6447 -> 6447 bytes
-rw-r--r--src/client/static/icons/favicon-16x16.png (renamed from src/client/static/favicon-16x16.png)bin1293 -> 1293 bytes
-rw-r--r--src/client/static/icons/favicon-32x32.png (renamed from src/client/static/favicon-32x32.png)bin2103 -> 2103 bytes
-rw-r--r--src/client/static/icons/mstile-150x150.png (renamed from src/client/static/mstile-150x150.png)bin3995 -> 3995 bytes
-rw-r--r--src/client/static/icons/safari-pinned-tab.svg (renamed from src/client/static/safari-pinned-tab.svg)0
-rw-r--r--src/client/static/manifest.beta.webmanifest29
-rw-r--r--src/client/static/manifest.json (renamed from src/client/static/manifest.webmanifest)0
-rw-r--r--src/client/static/sw.js29
-rw-r--r--src/client/static/untisinfo.css11
-rw-r--r--src/client/views/index.handlebars1
-rw-r--r--src/client/views/partials/head.handlebars10
-rw-r--r--src/server/lib/schools/hetmml/parseSchedule.js100
-rw-r--r--src/server/routes/getSchedule.js88
-rw-r--r--webpack.config.js58
-rw-r--r--yarn.lock457
45 files changed, 901 insertions, 354 deletions
diff --git a/.babelrc b/.babelrc
deleted file mode 100644
index 27b5c0d..0000000
--- a/.babelrc
+++ /dev/null
@@ -1,3 +0,0 @@
-{
- "presets": ["es2015", "react", "stage-2"]
-}
diff --git a/.bowerrc b/.bowerrc
deleted file mode 100644
index c7c43d3..0000000
--- a/.bowerrc
+++ /dev/null
@@ -1,3 +0,0 @@
-{
- "directory" : "src/client/static/components"
-}
diff --git a/.eslintrc.js b/.eslintrc.js
index da38fd5..9944cf8 100644
--- a/.eslintrc.js
+++ b/.eslintrc.js
@@ -7,10 +7,8 @@ module.exports = {
"jest": true,
},
"rules": {
- "strict": "off",
- "react/jsx-filename-extension": ["error", { "extensions": [".js"] }],
+ "react/jsx-filename-extension": "off",
"no-underscore-dangle": ["error", { "allow": ["_test"] }],
- "class-methods-use-this": "off",
"no-prototype-builtins": "off",
"react/forbid-prop-types": "off",
"react/prefer-stateless-function": "off",
diff --git a/.vscode/launch.json b/.vscode/launch.json
index 995ecf7..e70178d 100644
--- a/.vscode/launch.json
+++ b/.vscode/launch.json
@@ -2,26 +2,20 @@
"version": "0.2.0",
"configurations": [
{
+ "type": "node",
+ "request": "attach",
+ "name": "Attach to Node",
+ "processId": "${command:PickProcess}"
+ },
+ {
"type": "chrome",
"request": "launch",
- "name": "Client",
+ "name": "Google Chrome",
"url": "http://localhost:3000",
"webRoot": "${workspaceRoot}",
"sourceMapPathOverrides": {
"webpack:///*": "${webRoot}/*"
}
- },
- {
- "type": "node",
- "request": "launch",
- "name": "Server",
- "program": "${workspaceRoot}/src/server/bin/www"
}
],
- "compounds": [
- {
- "name": "Full-stack",
- "configurations": ["Server", "Client"]
- }
- ]
-} \ No newline at end of file
+}
diff --git a/.vscode/tasks.json b/.vscode/tasks.json
deleted file mode 100644
index fac4015..0000000
--- a/.vscode/tasks.json
+++ /dev/null
@@ -1,15 +0,0 @@
-{
- // See https://go.microsoft.com/fwlink/?LinkId=733558
- // for the documentation about the tasks.json format
- "version": "2.0.0",
- "tasks": [
- {
- "type": "npm",
- "script": "dev",
- "group": {
- "kind": "build",
- "isDefault": true
- }
- }
- ]
-} \ No newline at end of file
diff --git a/bower.json b/bower.json
deleted file mode 100644
index 0e80221..0000000
--- a/bower.json
+++ /dev/null
@@ -1,22 +0,0 @@
-{
- "name": "rooster",
- "description": "",
- "main": "app.js",
- "authors": [
- "Noah Loomans <noahloomans@gmail.com>"
- ],
- "license": "MIT",
- "homepage": "https://github.com/nloomans/rooster-mml",
- "private": true,
- "ignore": [
- "**/.*",
- "node_modules",
- "public/components",
- "test",
- "tests"
- ],
- "dependencies": {
- "sw-toolbox": "^3.3.0",
- "material-design-lite": "^1.3.0"
- }
-}
diff --git a/package.json b/package.json
index b602d8d..e0a47fd 100644
--- a/package.json
+++ b/package.json
@@ -6,27 +6,31 @@
"scripts": {
"start": "node ./src/server/bin/www",
"build": "webpack -p",
- "build:dev": "webpack --watch",
+ "build:dev": "webpack -wd",
"test": "jest",
- "test:dev": "jest --watch"
+ "test:dev": "jest --watch",
+ "lint": "eslint . --ignore-pattern src/client/static --ignore-pattern node_modules",
+ "lint:fix": "eslint . --ignore-pattern src/client/static --ignore-pattern node_modules --fix"
},
"jest": {
"transform": {
- "^.+\\.jsx?$": "babel-jest"
+ "^.+\\.js$": "babel-jest"
}
},
"dependencies": {
"axios": "^0.17.1",
+ "babel-polyfill": "^6.26.0",
"body-parser": "^1.16.0",
"cheerio": "^0.22.0",
"classnames": "^2.2.5",
"compression": "^1.6.2",
"dompurify": "^1.0.3",
"eslint": "^4.14.0",
- "express": "^4.13.4",
+ "express": "^4.16.3",
"express-handlebars": "^3.0.0",
"fuzzy-search": "^2.0.1",
"iconv-lite": "^0.4.17",
+ "jsdom": "^11.6.2",
"left-pad": "^1.1.1",
"lodash": "^4.15.0",
"moment": "^2.20.1",
@@ -40,8 +44,8 @@
"react-redux": "^5.0.6",
"react-router-dom": "^4.2.2",
"redux": "^3.7.2",
- "redux-logger": "^3.0.6",
- "rmwc": "^1.2.0"
+ "rmwc": "^1.2.0",
+ "whatwg-fetch": "^2.0.4"
},
"devDependencies": {
"babel-core": "^6.26.0",
@@ -60,6 +64,7 @@
"jest": "^21.2.1",
"node-sass": "^4.7.2",
"sass-loader": "^6.0.7",
+ "style-loader": "^0.20.3",
"webpack": "^3.5.6"
},
"author": "Noah Loomans <noahloomans@gmail.com>",
diff --git a/src/client/react/components/container/HelpBox.js b/src/client/react/components/container/HelpBox.js
index 31624db..8b53382 100644
--- a/src/client/react/components/container/HelpBox.js
+++ b/src/client/react/components/container/HelpBox.js
@@ -22,6 +22,8 @@ import React from 'react';
import PropTypes from 'prop-types';
import { connect } from 'react-redux';
+import './HelpBox.scss';
+
class HelpBox extends React.Component {
static propTypes = {
// redux
@@ -35,7 +37,7 @@ class HelpBox extends React.Component {
}
return (
- <div className="help-box">
+ <div className="HelpBox">
<div className="arrow" />
<div className="bubble">
Voer hier een docentafkorting, klas, leerlingnummer of lokaalnummer in.
diff --git a/src/client/react/components/container/HelpBox.scss b/src/client/react/components/container/HelpBox.scss
new file mode 100644
index 0000000..f91eb77
--- /dev/null
+++ b/src/client/react/components/container/HelpBox.scss
@@ -0,0 +1,23 @@
+.HelpBox {
+ position: relative;
+ margin-top: 32px;
+
+ .arrow {
+ position: absolute;
+ background-color: white;
+ width: 32px;
+ height: 32px;
+ top: -16px;
+ left: 48px;
+ transform: rotate(45deg);
+ }
+
+ .bubble {
+ position: relative;
+ background-color: white;
+ font-weight: bold;
+ margin: 16px;
+ padding: 16px;
+ border-radius: 4px;
+ }
+}
diff --git a/src/client/react/components/container/Menu.js b/src/client/react/components/container/Menu.js
index 920973b..0b5c4dc 100644
--- a/src/client/react/components/container/Menu.js
+++ b/src/client/react/components/container/Menu.js
@@ -28,6 +28,8 @@ import { Icon } from 'rmwc/Icon';
import users from '../../users';
import { setUser, userFromMatch } from '../../lib/url';
+import './Menu.scss';
+
class Menu extends React.Component {
static propTypes = {
// redux
@@ -59,19 +61,21 @@ class Menu extends React.Component {
render() {
return (
- <SimpleMenu
- handle={<Button><ButtonIcon use="more_vert" /></Button>}
- onSelected={(event) => {
- // Send the `data-type` of the selected <MenuItem />
- this.onItemSelected(event.detail.item.dataset.type);
- }}
- >
- <MenuItem data-type="add_label"><Icon use="bookmark_border" />Voeg label toe</MenuItem>
- <MenuItem data-type="make_favorite"><Icon use="star_border" />Maak favoriet</MenuItem>
- <div className="mdc-list-divider" role="separator" />
- <MenuItem data-type="room_finder"><Icon use="location_searching" />Lokaal zoeken</MenuItem>
- <MenuItem data-type="use_legacy_schedule"><Icon use="launch" />Oud rooster gebruiken</MenuItem>
- </SimpleMenu>
+ <div className="Menu">
+ <SimpleMenu
+ handle={<Button><ButtonIcon use="more_vert" /></Button>}
+ onSelected={(event) => {
+ // Send the `data-type` of the selected <MenuItem />
+ this.onItemSelected(event.detail.item.dataset.type);
+ }}
+ >
+ <MenuItem data-type="add_label"><Icon use="bookmark_border" />Voeg label toe</MenuItem>
+ <MenuItem data-type="make_favorite"><Icon use="star_border" />Maak favoriet</MenuItem>
+ <div className="mdc-list-divider" role="separator" />
+ <MenuItem data-type="room_finder"><Icon use="location_searching" />Lokaal zoeken</MenuItem>
+ <MenuItem data-type="use_legacy_schedule"><Icon use="launch" />Oud rooster gebruiken</MenuItem>
+ </SimpleMenu>
+ </div>
);
}
}
diff --git a/src/client/react/components/container/Menu.scss b/src/client/react/components/container/Menu.scss
new file mode 100644
index 0000000..3d84507
--- /dev/null
+++ b/src/client/react/components/container/Menu.scss
@@ -0,0 +1,25 @@
+.Menu {
+ .mdc-menu-anchor {
+ height: 100%;
+ }
+
+ .mdc-button {
+ height: 100%;
+ min-width: unset;
+ color: black;
+
+ &::before, &::after {
+ background-color: black;
+ }
+
+ i {
+ font-size: 24px;
+ }
+ }
+
+ .mdc-list-item {
+ i {
+ padding-right: 8px;
+ }
+ }
+}
diff --git a/src/client/react/components/container/Results.js b/src/client/react/components/container/Results.js
index 4fc9987..82e37cb 100644
--- a/src/client/react/components/container/Results.js
+++ b/src/client/react/components/container/Results.js
@@ -28,6 +28,8 @@ import users from '../../users';
import { setUser, userFromMatch } from '../../lib/url';
import Result from '../presentational/Result';
+import './Results.scss';
+
class Results extends React.Component {
static propTypes = {
results: PropTypes.arrayOf(PropTypes.string).isRequired,
@@ -56,8 +58,8 @@ class Results extends React.Component {
return (
<div
- className={classnames('search__results', {
- 'search__results--has-results': !isExactMatch && this.props.results.length > 0,
+ className={classnames('Results', {
+ hasResults: !isExactMatch && this.props.results.length > 0,
})}
style={{
minHeight: isExactMatch ? 0 : this.props.results.length * 54,
diff --git a/src/client/react/components/container/Results.scss b/src/client/react/components/container/Results.scss
new file mode 100644
index 0000000..60379cf
--- /dev/null
+++ b/src/client/react/components/container/Results.scss
@@ -0,0 +1,5 @@
+.Results {
+ &.hasResults {
+ border-top: 1px #BDBDBD solid;
+ }
+}
diff --git a/src/client/react/components/container/RoomFinder.js b/src/client/react/components/container/RoomFinder.js
index 97ed175..b729ee3 100644
--- a/src/client/react/components/container/RoomFinder.js
+++ b/src/client/react/components/container/RoomFinder.js
@@ -26,6 +26,8 @@ import { Button, ButtonIcon } from 'rmwc/Button';
import users from '../../users';
import { setUser, userFromMatch } from '../../lib/url';
+import './RoomFinder.scss';
+
class RoomFinder extends React.Component {
static propTypes = {
// redux
@@ -38,12 +40,6 @@ class RoomFinder extends React.Component {
history: PropTypes.object.isRequired,
}
- constructor(props) {
- super(props);
-
- this.changeRoom = this.changeRoom.bind(this);
- }
-
componentWillMount() {
const user = userFromMatch(this.props.match);
if (this.props.isVisible && users.byId[user].type !== 'r') {
@@ -81,12 +77,12 @@ class RoomFinder extends React.Component {
}
return (
- <div className="room-finder">
+ <div className="RoomFinder">
<Button onClick={() => this.changeRoom(-1)}>Vorige</Button>
<Button onClick={() => this.changeRoom(+1)}>Volgende</Button>
<div className="grow" />
<Button
- className="close-button"
+ className="closeButton"
onClick={() => this.props.dispatch({ type: 'ROOM_FINDER/HIDE' })}
>
<ButtonIcon use="close" />
diff --git a/src/client/react/components/container/RoomFinder.scss b/src/client/react/components/container/RoomFinder.scss
new file mode 100644
index 0000000..d4b16d9
--- /dev/null
+++ b/src/client/react/components/container/RoomFinder.scss
@@ -0,0 +1,23 @@
+.RoomFinder {
+ display: flex;
+ margin: 8px;
+ padding: 8px;
+ border-radius: 2px;
+ background-color: #D32F2F;
+
+ .mdc-button {
+ color: white;
+
+ &::before, &::after {
+ background-color: white;
+ }
+ }
+
+ .closeButton {
+ min-width: 48px;
+
+ .mdc-button__icon {
+ margin-right: 0;
+ }
+ }
+}
diff --git a/src/client/react/components/container/Search.js b/src/client/react/components/container/Search.js
index c968957..a124b21 100644
--- a/src/client/react/components/container/Search.js
+++ b/src/client/react/components/container/Search.js
@@ -33,6 +33,8 @@ import Menu from './Menu';
import Results from './Results';
import IconFromUserType from '../presentational/IconFromUserType';
+import './Search.scss';
+
class Search extends React.Component {
static propTypes = {
results: PropTypes.arrayOf(PropTypes.string).isRequired,
@@ -143,17 +145,17 @@ class Search extends React.Component {
searchText === users.byId[urlUser].value;
return (
- <div className="search">
- <div className={classnames('search-overflow', { 'search--has-focus': hasFocus })}>
- <div className="search__input-wrapper">
- <div className="search__icon-wrapper">
+ <div className="Search">
+ <div className={classnames('overflow', { hasFocus })}>
+ <div className="inputWrapper">
+ <div className="iconWrapper">
<IconFromUserType
userType={isExactMatch ? users.byId[urlUser].type : null}
defaultIcon={<SearchIcon />}
/>
</div>
<input
- id="search__input"
+ id="searchInput"
onChange={event => dispatch({ type: 'SEARCH/INPUT_CHANGE', searchText: event.target.value })}
onKeyDown={this.onKeyDown}
value={searchText}
diff --git a/src/client/react/components/container/Search.scss b/src/client/react/components/container/Search.scss
new file mode 100644
index 0000000..ef629c2
--- /dev/null
+++ b/src/client/react/components/container/Search.scss
@@ -0,0 +1,42 @@
+.Search {
+ height: 54px;
+ position: relative;
+
+ .overflow {
+ border-radius: 2px;
+ background-color: white;
+ position: absolute;
+ width: 100%;
+ box-shadow: 0 2px 2px 0 rgba(0,0,0,0.16), 0 0 0 1px rgba(0,0,0,0.08);
+
+ &.hasFocus {
+ box-shadow: 0 3px 8px 0 rgba(0,0,0,0.2), 0 0 0 1px rgba(0,0,0,0.08);
+ }
+
+ .inputWrapper {
+ display: flex;
+ height: 54px;
+
+ .iconWrapper {
+ height: 54px;
+ padding: 15px;
+
+ svg {
+ height: 24px;
+ width: 24px;
+ }
+ }
+
+ input {
+ border: 0;
+ background-color: transparent;
+ flex-grow: 1;
+ height: inherit;
+ padding: 16px;
+ padding-left: 0px;
+ font-size: 16px;
+ outline: none;
+ }
+ }
+ }
+}
diff --git a/src/client/react/components/container/WeekSelector.js b/src/client/react/components/container/WeekSelector.js
index 9a88af6..a8f5936 100644
--- a/src/client/react/components/container/WeekSelector.js
+++ b/src/client/react/components/container/WeekSelector.js
@@ -29,6 +29,8 @@ import ArrowForwardIcon from 'react-icons/lib/md/arrow-forward';
import purifyWeek from '../../lib/purifyWeek';
import { setWeek, weekFromLocation } from '../../lib/url';
+import './WeekSelector.scss';
+
class WeekSelector extends React.Component {
static propTypes = {
// react-router
@@ -67,7 +69,7 @@ class WeekSelector extends React.Component {
render() {
return (
- <div className="week-selector">
+ <div className="WeekSelector">
<button onClick={() => this.updateWeek(-1)}><ArrowBackIcon /></button>
<div className="text">{this.getWeekText()}</div>
<button onClick={() => this.updateWeek(+1)}><ArrowForwardIcon /></button>
diff --git a/src/client/react/components/container/WeekSelector.scss b/src/client/react/components/container/WeekSelector.scss
new file mode 100644
index 0000000..dd71fea
--- /dev/null
+++ b/src/client/react/components/container/WeekSelector.scss
@@ -0,0 +1,40 @@
+.WeekSelector {
+ display: flex;
+ padding: 8px;
+ padding-bottom: 0;
+ background-color: #F44336;
+ color: white;
+ align-items: center;
+
+ .text {
+ flex-grow: 1;
+ text-align: center;
+ }
+
+ button {
+ background-color: initial;
+ border: initial;
+ color: inherit;
+ padding: 8px;
+ border-radius: 4px;
+
+ svg {
+ font-size: 2em;
+ }
+
+ &:focus {
+ background-color: #D32F2F;
+ outline: none;
+ }
+
+ &:active {
+ background-color: #B81111;
+ outline: none;
+ }
+
+ &::-moz-focus-inner {
+ /* Remove the dotted line outline from Firefox */
+ border: 0;
+ }
+ }
+}
diff --git a/src/client/react/components/page/Index.js b/src/client/react/components/page/Index.js
index ac6c4f6..b2ebbcb 100644
--- a/src/client/react/components/page/Index.js
+++ b/src/client/react/components/page/Index.js
@@ -22,10 +22,12 @@ import React from 'react';
import Search from '../container/Search';
import HelpBox from '../container/HelpBox';
+import './Index.scss';
+
class IndexPage extends React.Component {
render() {
return (
- <div className="page-index">
+ <div className="IndexPage">
<div className="container">
<img src="/icons/mml-logo.png" alt="Metis" />
<Search />
diff --git a/src/client/react/components/page/Index.scss b/src/client/react/components/page/Index.scss
new file mode 100644
index 0000000..f47b36d
--- /dev/null
+++ b/src/client/react/components/page/Index.scss
@@ -0,0 +1,33 @@
+.IndexPage {
+ background-color: #ececec;
+ padding-top: calc(50vh - 310px);
+ height: 100vh;
+
+ .container {
+ max-width: 600px;
+ margin: 0 auto;
+ padding: 8px;
+
+ img {
+ display: block;
+ margin: 64px auto;
+ }
+
+ .Search {
+ z-index: 1; // Position search above help-box
+ }
+ }
+}
+
+
+@media (max-height: 510px) {
+ .IndexPage {
+ padding-top: 0px;
+
+ .container {
+ img {
+ display: none;
+ }
+ }
+ }
+}
diff --git a/src/client/react/components/page/User.js b/src/client/react/components/page/User.js
index 00fde7e..6f9373f 100644
--- a/src/client/react/components/page/User.js
+++ b/src/client/react/components/page/User.js
@@ -28,6 +28,8 @@ import { userFromMatch } from '../../lib/url';
import WeekSelector from '../container/WeekSelector';
import RoomFinder from '../container/RoomFinder';
+import './User.scss';
+
class UserPage extends React.Component {
static propTypes = {
// react-router
@@ -43,15 +45,15 @@ class UserPage extends React.Component {
}
return (
- <div className="page-user">
- <div className="search-wrapper">
- <div className="search-container">
+ <div className="UserPage">
+ <div className="searchWrapper">
+ <div className="searchContainer">
<Search />
</div>
</div>
<Elevation z={2}>
- <div className="menu">
- <div className="menu-container">
+ <div className="headerWrapper">
+ <div className="header">
<RoomFinder />
<WeekSelector />
</div>
diff --git a/src/client/react/components/page/User.scss b/src/client/react/components/page/User.scss
new file mode 100644
index 0000000..f56a593
--- /dev/null
+++ b/src/client/react/components/page/User.scss
@@ -0,0 +1,24 @@
+.UserPage {
+ .searchWrapper {
+ position: fixed;
+ z-index: 1; // Position the search bar abore the schedule
+ width: 100%;
+
+ .searchContainer {
+ max-width: 600px;
+ margin: 0 auto;
+ padding: 8px;
+ }
+ }
+
+ .headerWrapper {
+ background-color: #F44336;
+ padding-top: 54px;
+
+ .header {
+ max-width: 600px;
+ margin: 0 auto;
+ padding: 8px;
+ }
+ }
+}
diff --git a/src/client/react/components/presentational/Loading.js b/src/client/react/components/presentational/Loading.js
index e33720b..ce8f49a 100644
--- a/src/client/react/components/presentational/Loading.js
+++ b/src/client/react/components/presentational/Loading.js
@@ -24,7 +24,7 @@ import { LinearProgress } from 'rmwc/LinearProgress';
class Loading extends React.Component {
render() {
return (
- <div className="loading">
+ <div className="Loading">
<LinearProgress determinate={false} />
</div>
);
diff --git a/src/client/react/components/presentational/Loading.scss b/src/client/react/components/presentational/Loading.scss
new file mode 100644
index 0000000..5748899
--- /dev/null
+++ b/src/client/react/components/presentational/Loading.scss
@@ -0,0 +1,5 @@
+.Loading {
+ .mdc-linear-progress .mdc-linear-progress__bar-inner {
+ background-color: #9C27B0;
+ }
+}
diff --git a/src/client/react/components/presentational/Result.js b/src/client/react/components/presentational/Result.js
index 18e4eb9..900d3ac 100644
--- a/src/client/react/components/presentational/Result.js
+++ b/src/client/react/components/presentational/Result.js
@@ -25,6 +25,8 @@ import users from '../../users';
import IconFromUserType from './IconFromUserType';
+import './Result.scss';
+
class Result extends React.Component {
static propTypes = {
userId: PropTypes.string.isRequired,
@@ -34,20 +36,21 @@ class Result extends React.Component {
render() {
return (
- // eslint-disable-next-line
+ /* eslint-disable jsx-a11y/click-events-have-key-events */
+ /* eslint-disable jsx-a11y/no-static-element-interactions */
<div
- className={classnames('search__result', {
- 'search__result--selected': this.props.isSelected,
+ className={classnames('Result', {
+ isSelected: this.props.isSelected,
})}
onClick={this.props.onClick}
>
- <div className="search__icon-wrapper">
+ <div className="iconWrapper">
<IconFromUserType userType={users.byId[this.props.userId].type} />
</div>
- <div className="search__result__text">
+ <div className="text">
{users.byId[this.props.userId].value}
{users.byId[this.props.userId].alt &&
- <span className="search__result__text__alt">
+ <span className="alt">
{` ${users.byId[this.props.userId].alt}`}
</span>
}
diff --git a/src/client/react/components/presentational/Result.scss b/src/client/react/components/presentational/Result.scss
new file mode 100644
index 0000000..1ca0dd8
--- /dev/null
+++ b/src/client/react/components/presentational/Result.scss
@@ -0,0 +1,30 @@
+.Result {
+ display: flex;
+ cursor: pointer;
+
+ &:hover, &.isSelected {
+ background-color: lightgray;
+ }
+
+ .iconWrapper {
+ height: 54px;
+ padding: 15px;
+
+ svg {
+ height: 24px;
+ width: 24px;
+ }
+ }
+
+ .text {
+ padding: 15px;
+ padding-left: 0px;
+ font-size: 16px;
+ transform: translate(0, 3px);
+
+ .alt {
+ font-style: italic;
+ color: gray;
+ }
+ }
+}
diff --git a/src/client/react/index.js b/src/client/react/index.js
index 566c847..2a66f82 100644
--- a/src/client/react/index.js
+++ b/src/client/react/index.js
@@ -18,13 +18,14 @@
*
*/
+import 'babel-polyfill';
+import 'whatwg-fetch';
import React from 'react';
import ReactDOM from 'react-dom';
import moment from 'moment';
-import { createStore, applyMiddleware, compose } from 'redux';
+import { createStore } from 'redux';
import { Provider } from 'react-redux';
-import logger from 'redux-logger';
import {
BrowserRouter as Router,
@@ -37,14 +38,20 @@ import reducer from './reducers';
import Index from './components/page/Index';
import User from './components/page/User';
+import './index.scss';
+
+// Set the locale for moment.js to dutch. This ensures that the correct week
+// number logic is used.
moment.locale('nl');
-// eslint-disable-next-line no-underscore-dangle
-const composeEnhancers = window.__REDUX_DEVTOOLS_EXTENSION_COMPOSE__ || compose;
+/* eslint-disable no-underscore-dangle */
const store = createStore(
reducer,
- composeEnhancers(applyMiddleware(logger)),
+ // Redux devtools extension
+ // https://github.com/zalmoxisus/redux-devtools-extension
+ window.__REDUX_DEVTOOLS_EXTENSION__ && window.__REDUX_DEVTOOLS_EXTENSION__(),
);
+/* eslint-enable no-underscore-dangle */
ReactDOM.render(
<Provider store={store}>
@@ -56,9 +63,9 @@ ReactDOM.render(
</Switch>
</Router>
</Provider>,
- document.getElementById('root'),
+ document.querySelector('#root'),
);
// We only want to focus the input on page load. NOT on a in-javascript
// redirect. This is because that is when people usually want to start typing.
-document.querySelector('.search input').focus();
+document.querySelector('#searchInput').focus();
diff --git a/src/client/react/index.scss b/src/client/react/index.scss
new file mode 100644
index 0000000..4042d06
--- /dev/null
+++ b/src/client/react/index.scss
@@ -0,0 +1,12 @@
+* {
+ box-sizing: border-box;
+}
+
+body {
+ font-family: 'Roboto';
+ margin: 0;
+}
+
+:global(.grow) {
+ flex-grow: 1;
+}
diff --git a/src/client/static/browserconfig.xml b/src/client/static/browserconfig.xml
index b3930d0..6a1d00e 100644
--- a/src/client/static/browserconfig.xml
+++ b/src/client/static/browserconfig.xml
@@ -2,7 +2,7 @@
<browserconfig>
<msapplication>
<tile>
- <square150x150logo src="/mstile-150x150.png"/>
+ <square150x150logo src="/icons/mstile-150x150.png"/>
<TileColor>#da532c</TileColor>
</tile>
</msapplication>
diff --git a/src/client/static/apple-touch-icon.png b/src/client/static/icons/apple-touch-icon.png
index 5adfc69..5adfc69 100644
--- a/src/client/static/apple-touch-icon.png
+++ b/src/client/static/icons/apple-touch-icon.png
Binary files differ
diff --git a/src/client/static/favicon-16x16.png b/src/client/static/icons/favicon-16x16.png
index 1df47d3..1df47d3 100644
--- a/src/client/static/favicon-16x16.png
+++ b/src/client/static/icons/favicon-16x16.png
Binary files differ
diff --git a/src/client/static/favicon-32x32.png b/src/client/static/icons/favicon-32x32.png
index 36cd5da..36cd5da 100644
--- a/src/client/static/favicon-32x32.png
+++ b/src/client/static/icons/favicon-32x32.png
Binary files differ
diff --git a/src/client/static/mstile-150x150.png b/src/client/static/icons/mstile-150x150.png
index 5e381e6..5e381e6 100644
--- a/src/client/static/mstile-150x150.png
+++ b/src/client/static/icons/mstile-150x150.png
Binary files differ
diff --git a/src/client/static/safari-pinned-tab.svg b/src/client/static/icons/safari-pinned-tab.svg
index 97ce8bf..97ce8bf 100644
--- a/src/client/static/safari-pinned-tab.svg
+++ b/src/client/static/icons/safari-pinned-tab.svg
diff --git a/src/client/static/manifest.beta.webmanifest b/src/client/static/manifest.beta.webmanifest
deleted file mode 100644
index a1fdd92..0000000
--- a/src/client/static/manifest.beta.webmanifest
+++ /dev/null
@@ -1,29 +0,0 @@
-{
- "name": "BETA Metis Rooster",
- "short_name": "BETA Rooster",
- "start_url": "/",
- "display": "standalone",
- "background_color": "#ececec",
- "description": "Een verbeterde rooster pagina voor het metis",
- "icons": [{
- "src": "/icons/res/mipmap-mdpi/ic_launcher.png",
- "sizes": "48x48",
- "type": "image/png"
- }, {
- "src": "/icons/res/mipmap-hdpi/ic_launcher.png",
- "sizes": "72x72",
- "type": "image/png"
- }, {
- "src": "/icons/res/mipmap-xhdpi/ic_launcher.png",
- "sizes": "96x96",
- "type": "image/png"
- }, {
- "src": "/icons/res/mipmap-xxhdpi/ic_launcher.png",
- "sizes": "144x144",
- "type": "image/png"
- }, {
- "src": "/icons/res/mipmap-xxxhdpi/ic_launcher.png",
- "sizes": "192x192",
- "type": "image/png"
- }]
-}
diff --git a/src/client/static/manifest.webmanifest b/src/client/static/manifest.json
index d33ee8e..d33ee8e 100644
--- a/src/client/static/manifest.webmanifest
+++ b/src/client/static/manifest.json
diff --git a/src/client/static/sw.js b/src/client/static/sw.js
deleted file mode 100644
index bd43805..0000000
--- a/src/client/static/sw.js
+++ /dev/null
@@ -1,29 +0,0 @@
-/* global importScripts toolbox self */
-
-(global => {
- 'use strict'
-
- // Load the sw-toolbox library.
- importScripts('/components/sw-toolbox/sw-toolbox.js')
-
- // Ensure that our service worker takes control of the page as soon as possible.
- global.addEventListener('install', event => event.waitUntil(global.skipWaiting()))
- global.addEventListener('activate', event => event.waitUntil(global.clients.claim()))
-
- toolbox.precache([
- '/',
- '/hello',
- '/untisinfo.css',
- '/javascripts/bundle.js',
- '/stylesheets/style.css',
- '/stylesheets/hello.css'
- ])
-
- toolbox.router.get('/', toolbox.fastest)
- toolbox.router.get('/hello', toolbox.fastest)
-
- toolbox.router.get('/javascripts/bundle.js', toolbox.fastest)
- toolbox.router.get('/stylesheets/*', toolbox.fastest)
- toolbox.router.get('/untisinfo.css', toolbox.fastest)
- toolbox.router.get('/meetingpointProxy/*', toolbox.networkFirst)
-})(self)
diff --git a/src/client/static/untisinfo.css b/src/client/static/untisinfo.css
deleted file mode 100644
index d74a7aa..0000000
--- a/src/client/static/untisinfo.css
+++ /dev/null
@@ -1,11 +0,0 @@
-html, body {
- overflow: auto;
- width: 100vw;
- height: 100vh;
- margin: 0;
- -webkit-overflow-scrolling: touch;
-}
-
-center {
- margin: 5px;
-}
diff --git a/src/client/views/index.handlebars b/src/client/views/index.handlebars
index be6a075..5105439 100644
--- a/src/client/views/index.handlebars
+++ b/src/client/views/index.handlebars
@@ -24,7 +24,6 @@
<title>Metis Rooster</title>
<link rel="stylesheet" href="https://fonts.googleapis.com/icon?family=Material+Icons">
<link rel="stylesheet" href="https://unpkg.com/material-components-web@latest/dist/material-components-web.min.css">
- <link rel="stylesheet" href="/bundle.css">
</head>
<body>
<div id="root"></div>
diff --git a/src/client/views/partials/head.handlebars b/src/client/views/partials/head.handlebars
index 9801a95..9cf4023 100644
--- a/src/client/views/partials/head.handlebars
+++ b/src/client/views/partials/head.handlebars
@@ -23,8 +23,8 @@
<meta name="theme-color" content="#F44336">
<meta name="viewport" content="width=device-width initial-scale=1">
<link href="https://fonts.googleapis.com/css?family=Roboto" rel="stylesheet">
-<link rel="manifest" href="/manifest.webmanifest">
-<link rel="apple-touch-icon" sizes="120x120" href="/apple-touch-icon.png">
-<link rel="icon" type="image/png" href="/favicon-32x32.png" sizes="32x32">
-<link rel="icon" type="image/png" href="/favicon-16x16.png" sizes="16x16">
-<link rel="mask-icon" href="/safari-pinned-tab.svg" color="#f44336">
+<link rel="manifest" href="/manifest.json">
+<link rel="apple-touch-icon" sizes="120x120" href="/icons/apple-touch-icon.png">
+<link rel="icon" type="image/png" href="/icons/favicon-32x32.png" sizes="32x32">
+<link rel="icon" type="image/png" href="/icons/favicon-16x16.png" sizes="16x16">
+<link rel="mask-icon" href="/icons/safari-pinned-tab.svg" color="#f44336">
diff --git a/src/server/lib/schools/hetmml/parseSchedule.js b/src/server/lib/schools/hetmml/parseSchedule.js
new file mode 100644
index 0000000..14e861e
--- /dev/null
+++ b/src/server/lib/schools/hetmml/parseSchedule.js
@@ -0,0 +1,100 @@
+const { JSDOM } = require('jsdom');
+
+function fixFirstLargeScheduleItem(trNodeList) {
+ return Array.from(trNodeList).some((trNode, timeOfDay) => {
+ const tdNodeList = trNode.children;
+
+ return Array.from(tdNodeList).some((tdNode, dayOfWeek) => {
+ const height = tdNode.rowSpan / 2;
+ if (height === 1) {
+ return false;
+ }
+
+ tdNode.rowSpan = 2; // eslint-disable-line no-param-reassign
+
+ for (let i = 1; i < height; i += 1) {
+ // Are we at the end of the table?
+ if (dayOfWeek === 4) {
+ // If so, we cannot use insertBefore, because the is no node to insert
+ // it before. Use appendChild instead.
+ trNodeList[timeOfDay + i].appendChild(tdNode.cloneNode(true));
+ } else {
+ trNodeList[timeOfDay + i]
+ .insertBefore(
+ tdNode.cloneNode(true),
+ trNodeList[timeOfDay + i].children[dayOfWeek],
+ );
+ }
+ }
+
+ return true;
+ });
+ });
+}
+
+function parseSchedule(axiosResponse) {
+ const dom = new JSDOM(axiosResponse.data);
+ const { window } = dom;
+ const { document } = window;
+
+ const tableNode = document.querySelector('center > table');
+ const tbodyNode = tableNode.querySelector('tbody');
+ const trNodeList = tbodyNode.children;
+
+ Array.from(trNodeList).forEach((trNode, timeOfDay) => {
+ const tdNodeList = trNode.children;
+
+ if (timeOfDay === 0 || trNode.children.length === 0) {
+ tbodyNode.removeChild(trNode);
+ return;
+ }
+
+ Array.from(tdNodeList).forEach((tdNode, dayOfWeek) => {
+ if (dayOfWeek === 0) {
+ trNode.removeChild(tdNode);
+ }
+ });
+ });
+
+ let shouldContinue = true;
+ while (shouldContinue) {
+ shouldContinue = fixFirstLargeScheduleItem(trNodeList);
+ }
+
+ const scheduleItems = [];
+
+ Array.from(trNodeList).forEach((trNode, timeOfDay) => {
+ const tdNodeList = trNode.children;
+ Array.from(tdNodeList).forEach((tdNode, dayOfWeek) => {
+ if (tdNode.textContent.trim() === '') {
+ return;
+ }
+
+ const childTableNode = tdNode.querySelector('table');
+ const childTrNodeList = childTableNode.querySelectorAll('tr');
+
+ Array.from(childTrNodeList).forEach((childTrNode) => {
+ const subject = childTrNode.children[0].textContent.trim();
+ const attendees = childTrNode.children[1]
+ ? childTrNode.children[1].textContent.trim()
+ : undefined;
+ const location = childTrNode.children[2]
+ ? childTrNode.children[2].textContent.trim()
+ : undefined;
+
+ scheduleItems.push({
+ startTime: timeOfDay,
+ endTime: timeOfDay + 1,
+ dayOfWeek,
+ subject,
+ attendees,
+ location,
+ });
+ });
+ });
+ });
+
+ return scheduleItems;
+}
+
+module.exports = parseSchedule;
diff --git a/src/server/routes/getSchedule.js b/src/server/routes/getSchedule.js
index 04df28a..7a84dd2 100644
--- a/src/server/routes/getSchedule.js
+++ b/src/server/routes/getSchedule.js
@@ -25,11 +25,14 @@ const router = express.Router();
const getScheduleData = require('../lib/schools/hetmml/getScheduleData');
const getURLOfUser = require('../lib/schools/hetmml/getURLOfUser');
const axios = require('../lib/schools/hetmml/axios');
+const parseSchedule = require('../lib/schools/hetmml/parseSchedule');
// copied from http://www.meetingpointmco.nl/Roosters-AL/doc/dagroosters/untisscripts.js,
// were using the same code as they do to be sure that we always get the same
// week number.
-function getWeekNumber(target) {
+function currentWeekNumber() {
+ const target = new Date();
+
const dayNr = (target.getDay() + 6) % 7;
// eslint-disable-next-line
target.setDate(target.getDate() - dayNr + 3);
@@ -43,39 +46,58 @@ function getWeekNumber(target) {
return 1 + Math.ceil((firstThursday - target) / 604800000);
}
+async function getSchedule(userType, userValue, week, scheduleType = 'dag') {
+ const { users } = await getScheduleData();
+ const user =
+ users.filter(user_ => user_.type === userType && user_.value === userValue)[0];
+
+ if (!user) {
+ throw new Error(`${userType}/${userValue} is not in the user index.`);
+ }
+
+ if (!week) {
+ week = currentWeekNumber(); // eslint-disable-line no-param-reassign
+ }
+
+ const { index } = user;
+ const url = getURLOfUser(scheduleType, userType, index, week);
+
+ return axios.get(url);
+}
+
+router.get('/:type/:value.json', (req, res, next) => {
+ const { type, value } = req.params;
+ const { week, type: scheduleType } = req.query;
+
+ getSchedule(type, value, week, scheduleType)
+ .then((response) => {
+ const schedule = parseSchedule(response);
+ res.json(schedule);
+ })
+ .catch((err) => {
+ if (err.response) {
+ // eslint-disable-next-line no-param-reassign
+ err.status = err.response.status;
+ }
+ next(err);
+ });
+});
+
router.get('/:type/:value', (req, res, next) => {
- getScheduleData().then(({ users }) => {
- const { type, value } = req.params;
- let { week } = req.query;
- const user =
- users.filter(user_ => user_.type === type && user_.value === value)[0];
-
- if (!user) {
- next(new Error(`${type}/${value} is not in the user index.`));
- }
-
- if (!week) {
- week = getWeekNumber(new Date());
- }
-
- const { index } = user;
-
- const scheduleType = req.query.type || 'dag';
-
- const url = getURLOfUser(scheduleType, type, index, week);
-
- axios.get(url)
- .then((response) => {
- res.status(response.status).end(response.data);
- })
- .catch((err) => {
- if (err.response) {
- // eslint-disable-next-line no-param-reassign
- err.status = err.response.status;
- }
- next(err);
- });
- });
+ const { type, value } = req.params;
+ const { week, type: scheduleType } = req.query;
+
+ getSchedule(type, value, week, scheduleType)
+ .then((response) => {
+ res.status(response.status).end(response.data);
+ })
+ .catch((err) => {
+ if (err.response) {
+ // eslint-disable-next-line no-param-reassign
+ err.status = err.response.status;
+ }
+ next(err);
+ });
});
module.exports = router;
diff --git a/webpack.config.js b/webpack.config.js
index 0bf982a..f882566 100644
--- a/webpack.config.js
+++ b/webpack.config.js
@@ -1,8 +1,7 @@
const webpack = require('webpack');
const path = require('path');
-const ExtractTextPlugin = require('extract-text-webpack-plugin');
-const js = {
+module.exports = {
entry: './src/client/react/index.js',
output: {
path: path.resolve(__dirname, 'src/client/static'),
@@ -11,38 +10,43 @@ const js = {
module: {
rules: [
{
- test: [/\.js$/, /\.jsx$/],
+ test: /\.js$/,
exclude: [/node_modules/],
loader: 'babel-loader',
- options: { presets: ['es2015', 'react', 'stage-2'] },
+ options: {
+ presets: [
+ // Covert code to an older version of JavaScript. This allows us to
+ // use newer syntax (like classes) without having to working if it
+ // will work in IE9.
+ 'es2015',
+ // This converts the react code syntactical surger to their "plain"
+ // javascript equivalents.
+ // See https://reactjs.org/docs/introducing-jsx.html#jsx-represents-objects
+ 'react',
+ // This allows us the use newer JavaScript features that are still
+ // in the working. Examples are the spread operator (https://babeljs.io/docs/plugins/transform-object-rest-spread/),
+ // and class propreties (https://babeljs.io/docs/plugins/transform-class-properties/)
+ 'stage-2',
+ ],
+ },
},
- ],
- },
- plugins: [
- // Only load the dutch local for moment.js
- // https://stackoverflow.com/questions/25384360/how-to-prevent-moment-js-from-loading-locales-with-webpack#25426019
- new webpack.ContextReplacementPlugin(/moment[\/\\]locale$/, /nl/),
- ],
-};
-
-const style = {
- entry: './src/client/style/index.scss',
- output: {
- path: path.resolve(__dirname, 'src/client/static'),
- filename: 'bundle.css',
- },
- module: {
- rules: [
{
- test: [/\.scss$/],
- exclude: [/node_modules/],
- loader: ExtractTextPlugin.extract(['css-loader', 'sass-loader']),
+ // This allows us to import .scss files. When importing an .scss file
+ // from JavaScript, it will automatically be converted to normal css and
+ // injected to the head on page load.
+ test: /\.scss/,
+ use: [
+ { loader: 'style-loader' },
+ { loader: 'css-loader' },
+ { loader: 'sass-loader' },
+ ],
},
],
},
plugins: [
- new ExtractTextPlugin('bundle.css'),
+ // Only load the dutch local for moment.js. This is simply to reduce the
+ // side of the bundle that we send down to the browser.
+ // https://stackoverflow.com/questions/25384360/how-to-prevent-moment-js-from-loading-locales-with-webpack#25426019
+ new webpack.ContextReplacementPlugin(/moment[/\\]locale$/, /nl/),
],
};
-
-module.exports = [js, style];
diff --git a/yarn.lock b/yarn.lock
index 6918568..740b838 100644
--- a/yarn.lock
+++ b/yarn.lock
@@ -325,7 +325,7 @@
version "0.28.0"
resolved "https://registry.yarnpkg.com/@material/typography/-/typography-0.28.0.tgz#4ae96a852fcd324d61b649adc995326c431fcaea"
-abab@^1.0.3:
+abab@^1.0.3, abab@^1.0.4:
version "1.0.4"
resolved "https://registry.yarnpkg.com/abab/-/abab-1.0.4.tgz#5faad9c2c07f60dd76770f71cf025b62a63cfd4e"
@@ -340,6 +340,13 @@ accepts@~1.3.3:
mime-types "~2.1.16"
negotiator "0.6.1"
+accepts@~1.3.5:
+ version "1.3.5"
+ resolved "https://registry.yarnpkg.com/accepts/-/accepts-1.3.5.tgz#eb777df6011723a3b14e8a72c0805c8e86746bd2"
+ dependencies:
+ mime-types "~2.1.18"
+ negotiator "0.6.1"
+
acorn-dynamic-import@^2.0.0:
version "2.0.2"
resolved "https://registry.yarnpkg.com/acorn-dynamic-import/-/acorn-dynamic-import-2.0.2.tgz#c752bd210bef679501b6c6cb7fc84f8f47158cc4"
@@ -352,6 +359,12 @@ acorn-globals@^3.1.0:
dependencies:
acorn "^4.0.4"
+acorn-globals@^4.1.0:
+ version "4.1.0"
+ resolved "https://registry.yarnpkg.com/acorn-globals/-/acorn-globals-4.1.0.tgz#ab716025dbe17c54d3ef81d32ece2b2d99fe2538"
+ dependencies:
+ acorn "^5.0.0"
+
acorn-jsx@^3.0.0:
version "3.0.1"
resolved "https://registry.yarnpkg.com/acorn-jsx/-/acorn-jsx-3.0.1.tgz#afdf9488fb1ecefc8348f6fb22f464e32a58b36b"
@@ -374,6 +387,10 @@ acorn@^5.2.1:
version "5.2.1"
resolved "https://registry.yarnpkg.com/acorn/-/acorn-5.2.1.tgz#317ac7821826c22c702d66189ab8359675f135d7"
+acorn@^5.3.0:
+ version "5.5.3"
+ resolved "https://registry.yarnpkg.com/acorn/-/acorn-5.5.3.tgz#f473dd47e0277a08e28e9bec5aeeb04751f0b8c9"
+
ajv-keywords@^2.0.0:
version "2.1.0"
resolved "https://registry.yarnpkg.com/ajv-keywords/-/ajv-keywords-2.1.0.tgz#a296e17f7bfae7c1ce4f7e0de53d29cb32162df0"
@@ -382,6 +399,10 @@ ajv-keywords@^2.1.0:
version "2.1.1"
resolved "https://registry.yarnpkg.com/ajv-keywords/-/ajv-keywords-2.1.1.tgz#617997fc5f60576894c435f940d819e135b80762"
+ajv-keywords@^3.1.0:
+ version "3.1.0"
+ resolved "https://registry.yarnpkg.com/ajv-keywords/-/ajv-keywords-3.1.0.tgz#ac2b27939c543e95d2c06e7f7f5c27be4aa543be"
+
ajv@^4.9.1:
version "4.11.8"
resolved "https://registry.yarnpkg.com/ajv/-/ajv-4.11.8.tgz#82ffb02b29e662ae53bdc20af15947706739c536"
@@ -407,6 +428,14 @@ ajv@^5.1.5:
json-schema-traverse "^0.3.0"
json-stable-stringify "^1.0.1"
+ajv@^6.1.0:
+ version "6.3.0"
+ resolved "https://registry.yarnpkg.com/ajv/-/ajv-6.3.0.tgz#1650a41114ef00574cac10b8032d8f4c14812da7"
+ dependencies:
+ fast-deep-equal "^1.0.0"
+ fast-json-stable-stringify "^2.0.0"
+ json-schema-traverse "^0.3.0"
+
align-text@^0.1.1, align-text@^0.1.3:
version "0.1.4"
resolved "https://registry.yarnpkg.com/align-text/-/align-text-0.1.4.tgz#0cd90a561093f35d0a99256c22b7069433fad117"
@@ -580,6 +609,10 @@ async-foreach@^0.1.3:
version "0.1.3"
resolved "https://registry.yarnpkg.com/async-foreach/-/async-foreach-0.1.3.tgz#36121f845c0578172de419a97dbeb1d16ec34542"
+async-limiter@~1.0.0:
+ version "1.0.0"
+ resolved "https://registry.yarnpkg.com/async-limiter/-/async-limiter-1.0.0.tgz#78faed8c3d074ab81f22b4e985d79e8738f720f8"
+
async@^1.4.0:
version "1.5.2"
resolved "https://registry.yarnpkg.com/async/-/async-1.5.2.tgz#ec6a61ae56480c0c3cb241c95618e20892f9672a"
@@ -1163,6 +1196,14 @@ babel-plugin-transform-strict-mode@^6.24.1:
babel-runtime "^6.22.0"
babel-types "^6.24.1"
+babel-polyfill@^6.26.0:
+ version "6.26.0"
+ resolved "https://registry.yarnpkg.com/babel-polyfill/-/babel-polyfill-6.26.0.tgz#379937abc67d7895970adc621f284cd966cf2153"
+ dependencies:
+ babel-runtime "^6.26.0"
+ core-js "^2.5.0"
+ regenerator-runtime "^0.10.5"
+
babel-preset-es2015@^6.24.1:
version "6.24.1"
resolved "https://registry.yarnpkg.com/babel-preset-es2015/-/babel-preset-es2015-6.24.1.tgz#d44050d6bc2c9feea702aaf38d727a0210538939"
@@ -1335,6 +1376,21 @@ bn.js@^4.0.0, bn.js@^4.1.0, bn.js@^4.1.1, bn.js@^4.4.0:
version "4.11.8"
resolved "https://registry.yarnpkg.com/bn.js/-/bn.js-4.11.8.tgz#2cde09eb5ee341f484746bb0309b3253b1b1442f"
+body-parser@1.18.2:
+ version "1.18.2"
+ resolved "https://registry.yarnpkg.com/body-parser/-/body-parser-1.18.2.tgz#87678a19d84b47d859b83199bd59bce222b10454"
+ dependencies:
+ bytes "3.0.0"
+ content-type "~1.0.4"
+ debug "2.6.9"
+ depd "~1.1.1"
+ http-errors "~1.6.2"
+ iconv-lite "0.4.19"
+ on-finished "~2.3.0"
+ qs "6.5.1"
+ raw-body "2.3.2"
+ type-is "~1.6.15"
+
body-parser@^1.16.0:
version "1.17.2"
resolved "https://registry.yarnpkg.com/body-parser/-/body-parser-1.17.2.tgz#f8892abc8f9e627d42aedafbca66bf5ab99104ee"
@@ -1391,6 +1447,10 @@ brorand@^1.0.1:
version "1.1.0"
resolved "https://registry.yarnpkg.com/brorand/-/brorand-1.1.0.tgz#12c25efe40a45e3c323eb8675a0a0ce57b22371f"
+browser-process-hrtime@^0.1.2:
+ version "0.1.2"
+ resolved "https://registry.yarnpkg.com/browser-process-hrtime/-/browser-process-hrtime-0.1.2.tgz#425d68a58d3447f02a04aa894187fce8af8b7b8e"
+
browser-resolve@^1.11.2:
version "1.11.2"
resolved "https://registry.yarnpkg.com/browser-resolve/-/browser-resolve-1.11.2.tgz#8ff09b0a2c421718a1051c260b32e48f442938ce"
@@ -1489,6 +1549,10 @@ bytes@2.5.0:
version "2.5.0"
resolved "https://registry.yarnpkg.com/bytes/-/bytes-2.5.0.tgz#4c9423ea2d252c270c41b2bdefeff9bb6b62c06a"
+bytes@3.0.0:
+ version "3.0.0"
+ resolved "https://registry.yarnpkg.com/bytes/-/bytes-3.0.0.tgz#d32815404d689699f85a4ea4fa8755dd13a96048"
+
caller-path@^0.1.0:
version "0.1.0"
resolved "https://registry.yarnpkg.com/caller-path/-/caller-path-0.1.0.tgz#94085ef63581ecd3daa92444a8fe94e82577751f"
@@ -1800,7 +1864,7 @@ content-disposition@0.5.2:
version "0.5.2"
resolved "https://registry.yarnpkg.com/content-disposition/-/content-disposition-0.5.2.tgz#0cf68bb9ddf5f2be7961c3a85178cb85dba78cb4"
-content-type-parser@^1.0.1:
+content-type-parser@^1.0.1, content-type-parser@^1.0.2:
version "1.0.2"
resolved "https://registry.yarnpkg.com/content-type-parser/-/content-type-parser-1.0.2.tgz#caabe80623e63638b2502fd4c7f12ff4ce2352e7"
@@ -1808,6 +1872,10 @@ content-type@~1.0.2:
version "1.0.2"
resolved "https://registry.yarnpkg.com/content-type/-/content-type-1.0.2.tgz#b7d113aee7a8dd27bd21133c4dc2529df1721eed"
+content-type@~1.0.4:
+ version "1.0.4"
+ resolved "https://registry.yarnpkg.com/content-type/-/content-type-1.0.4.tgz#e138cc75e040c727b1966fe5e5f8c9aee256fe3b"
+
convert-source-map@^1.4.0:
version "1.5.1"
resolved "https://registry.yarnpkg.com/convert-source-map/-/convert-source-map-1.5.1.tgz#b8278097b9bc229365de5c62cf5fcaed8b5599e5"
@@ -2045,6 +2113,12 @@ debug@2.6.8, debug@^2.2.0, debug@^2.6.8:
dependencies:
ms "2.0.0"
+debug@2.6.9:
+ version "2.6.9"
+ resolved "https://registry.yarnpkg.com/debug/-/debug-2.6.9.tgz#5d128515df134ff327e90a4c93f4e077a536341f"
+ dependencies:
+ ms "2.0.0"
+
debug@^3.0.1, debug@^3.1.0:
version "3.1.0"
resolved "https://registry.yarnpkg.com/debug/-/debug-3.1.0.tgz#5bb5a0672628b64149566ba16819e61518c67261"
@@ -2065,10 +2139,6 @@ decode-uri-component@^0.2.0:
version "0.2.0"
resolved "https://registry.yarnpkg.com/decode-uri-component/-/decode-uri-component-0.2.0.tgz#eb3913333458775cb84cd1a1fae062106bb87545"
-deep-diff@^0.3.5:
- version "0.3.8"
- resolved "https://registry.yarnpkg.com/deep-diff/-/deep-diff-0.3.8.tgz#c01de63efb0eec9798801d40c7e0dae25b582c84"
-
deep-extend@~0.4.0:
version "0.4.2"
resolved "https://registry.yarnpkg.com/deep-extend/-/deep-extend-0.4.2.tgz#48b699c27e334bf89f10892be432f6e4c7d34a7f"
@@ -2122,6 +2192,10 @@ depd@1.1.1, depd@~1.1.0, depd@~1.1.1:
version "1.1.1"
resolved "https://registry.yarnpkg.com/depd/-/depd-1.1.1.tgz#5783b4e1c459f06fa5ca27f991f3d06e7a310359"
+depd@~1.1.2:
+ version "1.1.2"
+ resolved "https://registry.yarnpkg.com/depd/-/depd-1.1.2.tgz#9bcd52e14c097763e749b274c4346ed2e560b5a9"
+
des.js@^1.0.0:
version "1.0.0"
resolved "https://registry.yarnpkg.com/des.js/-/des.js-1.0.0.tgz#c074d2e2aa6a8a9a07dbd61f9a15c2cd83ec8ecc"
@@ -2187,6 +2261,12 @@ domelementtype@~1.1.1:
version "1.1.3"
resolved "https://registry.yarnpkg.com/domelementtype/-/domelementtype-1.1.3.tgz#bd28773e2642881aec51544924299c5cd822185b"
+domexception@^1.0.0:
+ version "1.0.1"
+ resolved "https://registry.yarnpkg.com/domexception/-/domexception-1.0.1.tgz#937442644ca6a31261ef36e3ec677fe805582c90"
+ dependencies:
+ webidl-conversions "^4.0.2"
+
domhandler@^2.3.0:
version "2.4.1"
resolved "https://registry.yarnpkg.com/domhandler/-/domhandler-2.4.1.tgz#892e47000a99be55bbf3774ffea0561d8879c259"
@@ -2245,9 +2325,9 @@ emojis-list@^2.0.0:
version "2.1.0"
resolved "https://registry.yarnpkg.com/emojis-list/-/emojis-list-2.1.0.tgz#4daa4d9db00f9819880c79fa457ae5b09a1fd389"
-encodeurl@~1.0.1:
- version "1.0.1"
- resolved "https://registry.yarnpkg.com/encodeurl/-/encodeurl-1.0.1.tgz#79e3d58655346909fe6f0f45a5de68103b294d20"
+encodeurl@~1.0.2:
+ version "1.0.2"
+ resolved "https://registry.yarnpkg.com/encodeurl/-/encodeurl-1.0.2.tgz#ad3ff4c86ec2d029322f5a02c3a9a606c95b3f59"
encoding@^0.1.11:
version "0.1.12"
@@ -2375,6 +2455,17 @@ escodegen@^1.6.1:
optionalDependencies:
source-map "~0.5.6"
+escodegen@^1.9.0:
+ version "1.9.1"
+ resolved "https://registry.yarnpkg.com/escodegen/-/escodegen-1.9.1.tgz#dbae17ef96c8e4bedb1356f4504fa4cc2f7cb7e2"
+ dependencies:
+ esprima "^3.1.3"
+ estraverse "^4.2.0"
+ esutils "^2.0.2"
+ optionator "^0.8.1"
+ optionalDependencies:
+ source-map "~0.6.1"
+
escope@^3.6.0:
version "3.6.0"
resolved "https://registry.yarnpkg.com/escope/-/escope-3.6.0.tgz#e01975e812781a163a6dadfdd80398dc64c889c3"
@@ -2543,9 +2634,9 @@ esutils@^2.0.2:
version "2.0.2"
resolved "https://registry.yarnpkg.com/esutils/-/esutils-2.0.2.tgz#0abf4f1caa5bcb1f7a9d8acc6dea4faaa04bac9b"
-etag@~1.8.0:
- version "1.8.0"
- resolved "https://registry.yarnpkg.com/etag/-/etag-1.8.0.tgz#6f631aef336d6c46362b51764044ce216be3c051"
+etag@~1.8.1:
+ version "1.8.1"
+ resolved "https://registry.yarnpkg.com/etag/-/etag-1.8.1.tgz#41ae2eeb65efa62268aebfea83ac7d79299b0887"
event-emitter@~0.3.5:
version "0.3.5"
@@ -2616,38 +2707,40 @@ express-handlebars@^3.0.0:
object.assign "^4.0.3"
promise "^7.0.0"
-express@^4.13.4:
- version "4.15.4"
- resolved "https://registry.yarnpkg.com/express/-/express-4.15.4.tgz#032e2253489cf8fce02666beca3d11ed7a2daed1"
+express@^4.16.3:
+ version "4.16.3"
+ resolved "https://registry.yarnpkg.com/express/-/express-4.16.3.tgz#6af8a502350db3246ecc4becf6b5a34d22f7ed53"
dependencies:
- accepts "~1.3.3"
+ accepts "~1.3.5"
array-flatten "1.1.1"
+ body-parser "1.18.2"
content-disposition "0.5.2"
- content-type "~1.0.2"
+ content-type "~1.0.4"
cookie "0.3.1"
cookie-signature "1.0.6"
- debug "2.6.8"
- depd "~1.1.1"
- encodeurl "~1.0.1"
+ debug "2.6.9"
+ depd "~1.1.2"
+ encodeurl "~1.0.2"
escape-html "~1.0.3"
- etag "~1.8.0"
- finalhandler "~1.0.4"
- fresh "0.5.0"
+ etag "~1.8.1"
+ finalhandler "1.1.1"
+ fresh "0.5.2"
merge-descriptors "1.0.1"
methods "~1.1.2"
on-finished "~2.3.0"
- parseurl "~1.3.1"
+ parseurl "~1.3.2"
path-to-regexp "0.1.7"
- proxy-addr "~1.1.5"
- qs "6.5.0"
+ proxy-addr "~2.0.3"
+ qs "6.5.1"
range-parser "~1.2.0"
- send "0.15.4"
- serve-static "1.12.4"
- setprototypeof "1.0.3"
- statuses "~1.3.1"
- type-is "~1.6.15"
- utils-merge "1.0.0"
- vary "~1.1.1"
+ safe-buffer "5.1.1"
+ send "0.16.2"
+ serve-static "1.13.2"
+ setprototypeof "1.1.0"
+ statuses "~1.4.0"
+ type-is "~1.6.16"
+ utils-merge "1.0.1"
+ vary "~1.1.2"
extend@~3.0.0, extend@~3.0.1:
version "3.0.1"
@@ -2748,16 +2841,16 @@ fill-range@^2.1.0:
repeat-element "^1.1.2"
repeat-string "^1.5.2"
-finalhandler@~1.0.4:
- version "1.0.4"
- resolved "https://registry.yarnpkg.com/finalhandler/-/finalhandler-1.0.4.tgz#18574f2e7c4b98b8ae3b230c21f201f31bdb3fb7"
+finalhandler@1.1.1:
+ version "1.1.1"
+ resolved "https://registry.yarnpkg.com/finalhandler/-/finalhandler-1.1.1.tgz#eebf4ed840079c83f4249038c9d703008301b105"
dependencies:
- debug "2.6.8"
- encodeurl "~1.0.1"
+ debug "2.6.9"
+ encodeurl "~1.0.2"
escape-html "~1.0.3"
on-finished "~2.3.0"
- parseurl "~1.3.1"
- statuses "~1.3.1"
+ parseurl "~1.3.2"
+ statuses "~1.4.0"
unpipe "~1.0.0"
find-cache-dir@^1.0.0:
@@ -2850,13 +2943,13 @@ form-data@~2.3.1:
combined-stream "^1.0.5"
mime-types "^2.1.12"
-forwarded@~0.1.0:
- version "0.1.0"
- resolved "https://registry.yarnpkg.com/forwarded/-/forwarded-0.1.0.tgz#19ef9874c4ae1c297bcf078fde63a09b66a84363"
+forwarded@~0.1.2:
+ version "0.1.2"
+ resolved "https://registry.yarnpkg.com/forwarded/-/forwarded-0.1.2.tgz#98c23dab1175657b8c0573e8ceccd91b0ff18c84"
-fresh@0.5.0:
- version "0.5.0"
- resolved "https://registry.yarnpkg.com/fresh/-/fresh-0.5.0.tgz#f474ca5e6a9246d6fd8e0953cfa9b9c805afa78e"
+fresh@0.5.2:
+ version "0.5.2"
+ resolved "https://registry.yarnpkg.com/fresh/-/fresh-0.5.2.tgz#3d8cadd90d976569fa835ab1f8e4b23a105605a7"
fs.realpath@^1.0.0:
version "1.0.0"
@@ -3181,7 +3274,7 @@ html-comment-regex@^1.1.0:
version "1.1.1"
resolved "https://registry.yarnpkg.com/html-comment-regex/-/html-comment-regex-1.1.1.tgz#668b93776eaae55ebde8f3ad464b307a4963625e"
-html-encoding-sniffer@^1.0.1:
+html-encoding-sniffer@^1.0.1, html-encoding-sniffer@^1.0.2:
version "1.0.2"
resolved "https://registry.yarnpkg.com/html-encoding-sniffer/-/html-encoding-sniffer-1.0.2.tgz#e70d84b94da53aa375e11fe3a351be6642ca46f8"
dependencies:
@@ -3198,7 +3291,7 @@ htmlparser2@^3.9.1:
inherits "^2.0.1"
readable-stream "^2.0.2"
-http-errors@~1.6.1, http-errors@~1.6.2:
+http-errors@1.6.2, http-errors@~1.6.1, http-errors@~1.6.2:
version "1.6.2"
resolved "https://registry.yarnpkg.com/http-errors/-/http-errors-1.6.2.tgz#0a002cc85707192a7e7946ceedc11155f60ec736"
dependencies:
@@ -3331,9 +3424,9 @@ invert-kv@^1.0.0:
version "1.0.0"
resolved "https://registry.yarnpkg.com/invert-kv/-/invert-kv-1.0.0.tgz#104a8e4aaca6d3d8cd157a8ef8bfab2d7a3ffdb6"
-ipaddr.js@1.4.0:
- version "1.4.0"
- resolved "https://registry.yarnpkg.com/ipaddr.js/-/ipaddr.js-1.4.0.tgz#296aca878a821816e5b85d0a285a99bcff4582f0"
+ipaddr.js@1.6.0:
+ version "1.6.0"
+ resolved "https://registry.yarnpkg.com/ipaddr.js/-/ipaddr.js-1.6.0.tgz#e3fa357b773da619f26e95f049d055c72796f86b"
is-absolute-url@^2.0.0:
version "2.1.0"
@@ -3862,6 +3955,37 @@ jsbn@~0.1.0:
version "0.1.1"
resolved "https://registry.yarnpkg.com/jsbn/-/jsbn-0.1.1.tgz#a5e654c2e5a2deb5f201d96cefbca80c0ef2f513"
+jsdom@^11.6.2:
+ version "11.6.2"
+ resolved "https://registry.yarnpkg.com/jsdom/-/jsdom-11.6.2.tgz#25d1ef332d48adf77fc5221fe2619967923f16bb"
+ dependencies:
+ abab "^1.0.4"
+ acorn "^5.3.0"
+ acorn-globals "^4.1.0"
+ array-equal "^1.0.0"
+ browser-process-hrtime "^0.1.2"
+ content-type-parser "^1.0.2"
+ cssom ">= 0.3.2 < 0.4.0"
+ cssstyle ">= 0.2.37 < 0.3.0"
+ domexception "^1.0.0"
+ escodegen "^1.9.0"
+ html-encoding-sniffer "^1.0.2"
+ left-pad "^1.2.0"
+ nwmatcher "^1.4.3"
+ parse5 "4.0.0"
+ pn "^1.1.0"
+ request "^2.83.0"
+ request-promise-native "^1.0.5"
+ sax "^1.2.4"
+ symbol-tree "^3.2.2"
+ tough-cookie "^2.3.3"
+ w3c-hr-time "^1.0.1"
+ webidl-conversions "^4.0.2"
+ whatwg-encoding "^1.0.3"
+ whatwg-url "^6.4.0"
+ ws "^4.0.0"
+ xml-name-validator "^3.0.0"
+
jsdom@^9.12.0:
version "9.12.0"
resolved "https://registry.yarnpkg.com/jsdom/-/jsdom-9.12.0.tgz#e8c546fffcb06c00d4833ca84410fed7f8a097d4"
@@ -3985,6 +4109,10 @@ left-pad@^1.1.1:
version "1.1.3"
resolved "https://registry.yarnpkg.com/left-pad/-/left-pad-1.1.3.tgz#612f61c033f3a9e08e939f1caebeea41b6f3199a"
+left-pad@^1.2.0:
+ version "1.2.0"
+ resolved "https://registry.yarnpkg.com/left-pad/-/left-pad-1.2.0.tgz#d30a73c6b8201d8f7d8e7956ba9616087a68e0ee"
+
leven@^2.1.0:
version "2.1.0"
resolved "https://registry.yarnpkg.com/leven/-/leven-2.1.0.tgz#c2e7a9f772094dee9d34202ae8acce4687875580"
@@ -4110,6 +4238,10 @@ lodash.some@^4.4.0:
version "4.6.0"
resolved "https://registry.yarnpkg.com/lodash.some/-/lodash.some-4.6.0.tgz#1bb9f314ef6b8baded13b549169b2a945eb68e4d"
+lodash.sortby@^4.7.0:
+ version "4.7.0"
+ resolved "https://registry.yarnpkg.com/lodash.sortby/-/lodash.sortby-4.7.0.tgz#edd14c824e2cc9c1e0b0a1b42bb5210516a42438"
+
lodash.tail@^4.1.1:
version "4.1.1"
resolved "https://registry.yarnpkg.com/lodash.tail/-/lodash.tail-4.1.1.tgz#d2333a36d9e7717c8ad2f7cacafec7c32b444664"
@@ -4118,7 +4250,7 @@ lodash.uniq@^4.5.0:
version "4.5.0"
resolved "https://registry.yarnpkg.com/lodash.uniq/-/lodash.uniq-4.5.0.tgz#d0225373aeb652adc1bc82e4945339a842754773"
-lodash@^4.0.0, lodash@~4.17.4:
+lodash@^4.0.0, lodash@^4.13.1, lodash@~4.17.4:
version "4.17.5"
resolved "https://registry.yarnpkg.com/lodash/-/lodash-4.17.5.tgz#99a92d65c0272debe8c96b6057bc8fbfa3bed511"
@@ -4291,15 +4423,25 @@ miller-rabin@^4.0.0:
version "1.30.0"
resolved "https://registry.yarnpkg.com/mime-db/-/mime-db-1.30.0.tgz#74c643da2dd9d6a45399963465b26d5ca7d71f01"
+mime-db@~1.33.0:
+ version "1.33.0"
+ resolved "https://registry.yarnpkg.com/mime-db/-/mime-db-1.33.0.tgz#a3492050a5cb9b63450541e39d9788d2272783db"
+
mime-types@^2.1.12, mime-types@~2.1.15, mime-types@~2.1.16, mime-types@~2.1.17, mime-types@~2.1.7:
version "2.1.17"
resolved "https://registry.yarnpkg.com/mime-types/-/mime-types-2.1.17.tgz#09d7a393f03e995a79f8af857b70a9e0ab16557a"
dependencies:
mime-db "~1.30.0"
-mime@1.3.4:
- version "1.3.4"
- resolved "https://registry.yarnpkg.com/mime/-/mime-1.3.4.tgz#115f9e3b6b3daf2959983cb38f149a2d40eb5d53"
+mime-types@~2.1.18:
+ version "2.1.18"
+ resolved "https://registry.yarnpkg.com/mime-types/-/mime-types-2.1.18.tgz#6f323f60a83d11146f831ff11fd66e2fe5503bb8"
+ dependencies:
+ mime-db "~1.33.0"
+
+mime@1.4.1:
+ version "1.4.1"
+ resolved "https://registry.yarnpkg.com/mime/-/mime-1.4.1.tgz#121f9ebc49e3766f311a76e1fa1c8003c4b03aa6"
mimic-fn@^1.0.0:
version "1.1.0"
@@ -4584,6 +4726,10 @@ number-is-nan@^1.0.0:
version "1.4.3"
resolved "https://registry.yarnpkg.com/nwmatcher/-/nwmatcher-1.4.3.tgz#64348e3b3d80f035b40ac11563d278f8b72db89c"
+nwmatcher@^1.4.3:
+ version "1.4.4"
+ resolved "https://registry.yarnpkg.com/nwmatcher/-/nwmatcher-1.4.4.tgz#2285631f34a95f0d0395cd900c96ed39b58f346e"
+
oauth-sign@~0.8.1, oauth-sign@~0.8.2:
version "0.8.2"
resolved "https://registry.yarnpkg.com/oauth-sign/-/oauth-sign-0.8.2.tgz#46a6ab7f0aead8deae9ec0565780b7d4efeb9d43"
@@ -4739,13 +4885,17 @@ parse-json@^2.2.0:
dependencies:
error-ex "^1.2.0"
+parse5@4.0.0:
+ version "4.0.0"
+ resolved "https://registry.yarnpkg.com/parse5/-/parse5-4.0.0.tgz#6d78656e3da8d78b4ec0b906f7c08ef1dfe3f608"
+
parse5@^1.5.1:
version "1.5.1"
resolved "https://registry.yarnpkg.com/parse5/-/parse5-1.5.1.tgz#9b7f3b0de32be78dc2401b17573ccaf0f6f59d94"
-parseurl@~1.3.1:
- version "1.3.1"
- resolved "https://registry.yarnpkg.com/parseurl/-/parseurl-1.3.1.tgz#c8ab8c9223ba34888aa64a297b28853bec18da56"
+parseurl@~1.3.2:
+ version "1.3.2"
+ resolved "https://registry.yarnpkg.com/parseurl/-/parseurl-1.3.2.tgz#fc289d4ed8993119460c156253262cdc8de65bf3"
path-browserify@0.0.0:
version "0.0.0"
@@ -4853,6 +5003,10 @@ pluralize@^7.0.0:
version "7.0.0"
resolved "https://registry.yarnpkg.com/pluralize/-/pluralize-7.0.0.tgz#298b89df8b93b0221dbf421ad2b1b1ea23fc6777"
+pn@^1.1.0:
+ version "1.1.0"
+ resolved "https://registry.yarnpkg.com/pn/-/pn-1.1.0.tgz#e2f4cef0e219f463c179ab37463e4e1ecdccbafb"
+
postcss-calc@^5.2.0:
version "5.3.1"
resolved "https://registry.yarnpkg.com/postcss-calc/-/postcss-calc-5.3.1.tgz#77bae7ca928ad85716e2fda42f261bf7c1d65b5e"
@@ -5152,12 +5306,12 @@ prop-types@^15.5.10, prop-types@^15.5.4, prop-types@^15.6.0:
loose-envify "^1.3.1"
object-assign "^4.1.1"
-proxy-addr@~1.1.5:
- version "1.1.5"
- resolved "https://registry.yarnpkg.com/proxy-addr/-/proxy-addr-1.1.5.tgz#71c0ee3b102de3f202f3b64f608d173fcba1a918"
+proxy-addr@~2.0.3:
+ version "2.0.3"
+ resolved "https://registry.yarnpkg.com/proxy-addr/-/proxy-addr-2.0.3.tgz#355f262505a621646b3130a728eb647e22055341"
dependencies:
- forwarded "~0.1.0"
- ipaddr.js "1.4.0"
+ forwarded "~0.1.2"
+ ipaddr.js "1.6.0"
prr@~0.0.0:
version "0.0.0"
@@ -5189,6 +5343,10 @@ punycode@^1.2.4, punycode@^1.4.1:
version "1.4.1"
resolved "https://registry.yarnpkg.com/punycode/-/punycode-1.4.1.tgz#c0d5a63b2718800ad8e1eb0fa5269c84dd41845e"
+punycode@^2.1.0:
+ version "2.1.0"
+ resolved "https://registry.yarnpkg.com/punycode/-/punycode-2.1.0.tgz#5f863edc89b96db09074bad7947bf09056ca4e7d"
+
q@^1.1.2:
version "1.5.1"
resolved "https://registry.yarnpkg.com/q/-/q-1.5.1.tgz#7e32f75b41381291d04611f1bf14109ac00651d7"
@@ -5197,18 +5355,14 @@ qs@6.4.0, qs@~6.4.0:
version "6.4.0"
resolved "https://registry.yarnpkg.com/qs/-/qs-6.4.0.tgz#13e26d28ad6b0ffaa91312cd3bf708ed351e7233"
-qs@6.5.0:
- version "6.5.0"
- resolved "https://registry.yarnpkg.com/qs/-/qs-6.5.0.tgz#8d04954d364def3efc55b5a0793e1e2c8b1e6e49"
+qs@6.5.1, qs@~6.5.1:
+ version "6.5.1"
+ resolved "https://registry.yarnpkg.com/qs/-/qs-6.5.1.tgz#349cdf6eef89ec45c12d7d5eb3fc0c870343a6d8"
qs@~6.3.0:
version "6.3.2"
resolved "https://registry.yarnpkg.com/qs/-/qs-6.3.2.tgz#e75bd5f6e268122a2a0e0bda630b2550c166502c"
-qs@~6.5.1:
- version "6.5.1"
- resolved "https://registry.yarnpkg.com/qs/-/qs-6.5.1.tgz#349cdf6eef89ec45c12d7d5eb3fc0c870343a6d8"
-
query-string@^4.1.0:
version "4.3.4"
resolved "https://registry.yarnpkg.com/query-string/-/query-string-4.3.4.tgz#bbb693b9ca915c232515b228b1a02b609043dbeb"
@@ -5249,6 +5403,15 @@ range-parser@~1.2.0:
version "1.2.0"
resolved "https://registry.yarnpkg.com/range-parser/-/range-parser-1.2.0.tgz#f49be6b487894ddc40dcc94a322f611092e00d5e"
+raw-body@2.3.2:
+ version "2.3.2"
+ resolved "https://registry.yarnpkg.com/raw-body/-/raw-body-2.3.2.tgz#bcd60c77d3eb93cde0050295c3f379389bc88f89"
+ dependencies:
+ bytes "3.0.0"
+ http-errors "1.6.2"
+ iconv-lite "0.4.19"
+ unpipe "1.0.0"
+
raw-body@~2.2.0:
version "2.2.0"
resolved "https://registry.yarnpkg.com/raw-body/-/raw-body-2.2.0.tgz#994976cf6a5096a41162840492f0bdc5d6e7fb96"
@@ -5400,12 +5563,6 @@ reduce-function-call@^1.0.1:
dependencies:
balanced-match "^0.4.2"
-redux-logger@^3.0.6:
- version "3.0.6"
- resolved "https://registry.yarnpkg.com/redux-logger/-/redux-logger-3.0.6.tgz#f7555966f3098f3c88604c449cf0baf5778274bf"
- dependencies:
- deep-diff "^0.3.5"
-
redux@^3.7.2:
version "3.7.2"
resolved "https://registry.yarnpkg.com/redux/-/redux-3.7.2.tgz#06b73123215901d25d065be342eb026bc1c8537b"
@@ -5419,6 +5576,10 @@ regenerate@^1.2.1:
version "1.3.2"
resolved "https://registry.yarnpkg.com/regenerate/-/regenerate-1.3.2.tgz#d1941c67bad437e1be76433add5b385f95b19260"
+regenerator-runtime@^0.10.5:
+ version "0.10.5"
+ resolved "https://registry.yarnpkg.com/regenerator-runtime/-/regenerator-runtime-0.10.5.tgz#336c3efc1220adcedda2c9fab67b5a7955a33658"
+
regenerator-runtime@^0.11.0:
version "0.11.0"
resolved "https://registry.yarnpkg.com/regenerator-runtime/-/regenerator-runtime-0.11.0.tgz#7e54fe5b5ccd5d6624ea6255c3473be090b802e1"
@@ -5481,7 +5642,21 @@ repeating@^2.0.0:
dependencies:
is-finite "^1.0.0"
-request@2:
+request-promise-core@1.1.1:
+ version "1.1.1"
+ resolved "https://registry.yarnpkg.com/request-promise-core/-/request-promise-core-1.1.1.tgz#3eee00b2c5aa83239cfb04c5700da36f81cd08b6"
+ dependencies:
+ lodash "^4.13.1"
+
+request-promise-native@^1.0.5:
+ version "1.0.5"
+ resolved "https://registry.yarnpkg.com/request-promise-native/-/request-promise-native-1.0.5.tgz#5281770f68e0c9719e5163fd3fab482215f4fda5"
+ dependencies:
+ request-promise-core "1.1.1"
+ stealthy-require "^1.1.0"
+ tough-cookie ">=2.3.3"
+
+request@2, request@^2.83.0:
version "2.85.0"
resolved "https://registry.yarnpkg.com/request/-/request-2.85.0.tgz#5a03615a47c61420b3eb99b7dba204f83603e1fa"
dependencies:
@@ -5712,7 +5887,7 @@ sass-loader@^6.0.7:
neo-async "^2.5.0"
pify "^3.0.0"
-sax@^1.2.1, sax@~1.2.1:
+sax@^1.2.1, sax@^1.2.4, sax@~1.2.1:
version "1.2.4"
resolved "https://registry.yarnpkg.com/sax/-/sax-1.2.4.tgz#2816234e2378bddc4e5354fab5caa895df7100d9"
@@ -5722,6 +5897,13 @@ schema-utils@^0.3.0:
dependencies:
ajv "^5.0.0"
+schema-utils@^0.4.5:
+ version "0.4.5"
+ resolved "https://registry.yarnpkg.com/schema-utils/-/schema-utils-0.4.5.tgz#21836f0608aac17b78f9e3e24daff14a5ca13a3e"
+ dependencies:
+ ajv "^6.1.0"
+ ajv-keywords "^3.1.0"
+
scss-tokenizer@^0.2.3:
version "0.2.3"
resolved "https://registry.yarnpkg.com/scss-tokenizer/-/scss-tokenizer-0.2.3.tgz#8eb06db9a9723333824d3f5530641149847ce5d1"
@@ -5737,32 +5919,32 @@ semver@~5.3.0:
version "5.3.0"
resolved "https://registry.yarnpkg.com/semver/-/semver-5.3.0.tgz#9b2ce5d3de02d17c6012ad326aa6b4d0cf54f94f"
-send@0.15.4:
- version "0.15.4"
- resolved "https://registry.yarnpkg.com/send/-/send-0.15.4.tgz#985faa3e284b0273c793364a35c6737bd93905b9"
+send@0.16.2:
+ version "0.16.2"
+ resolved "https://registry.yarnpkg.com/send/-/send-0.16.2.tgz#6ecca1e0f8c156d141597559848df64730a6bbc1"
dependencies:
- debug "2.6.8"
- depd "~1.1.1"
+ debug "2.6.9"
+ depd "~1.1.2"
destroy "~1.0.4"
- encodeurl "~1.0.1"
+ encodeurl "~1.0.2"
escape-html "~1.0.3"
- etag "~1.8.0"
- fresh "0.5.0"
+ etag "~1.8.1"
+ fresh "0.5.2"
http-errors "~1.6.2"
- mime "1.3.4"
+ mime "1.4.1"
ms "2.0.0"
on-finished "~2.3.0"
range-parser "~1.2.0"
- statuses "~1.3.1"
+ statuses "~1.4.0"
-serve-static@1.12.4:
- version "1.12.4"
- resolved "https://registry.yarnpkg.com/serve-static/-/serve-static-1.12.4.tgz#9b6aa98eeb7253c4eedc4c1f6fdbca609901a961"
+serve-static@1.13.2:
+ version "1.13.2"
+ resolved "https://registry.yarnpkg.com/serve-static/-/serve-static-1.13.2.tgz#095e8472fd5b46237db50ce486a43f4b86c6cec1"
dependencies:
- encodeurl "~1.0.1"
+ encodeurl "~1.0.2"
escape-html "~1.0.3"
- parseurl "~1.3.1"
- send "0.15.4"
+ parseurl "~1.3.2"
+ send "0.16.2"
set-blocking@^2.0.0, set-blocking@~2.0.0:
version "2.0.0"
@@ -5780,6 +5962,10 @@ setprototypeof@1.0.3:
version "1.0.3"
resolved "https://registry.yarnpkg.com/setprototypeof/-/setprototypeof-1.0.3.tgz#66567e37043eeb4f04d91bd658c0cbefb55b8e04"
+setprototypeof@1.1.0:
+ version "1.1.0"
+ resolved "https://registry.yarnpkg.com/setprototypeof/-/setprototypeof-1.1.0.tgz#d0bd85536887b6fe7c0d818cb962d9d91c54e656"
+
sha.js@^2.4.0, sha.js@^2.4.8:
version "2.4.8"
resolved "https://registry.yarnpkg.com/sha.js/-/sha.js-2.4.8.tgz#37068c2c476b6baf402d14a49c67f597921f634f"
@@ -5860,7 +6046,7 @@ source-map@^0.5.3, source-map@^0.5.6, source-map@~0.5.1, source-map@~0.5.3, sour
version "0.5.7"
resolved "https://registry.yarnpkg.com/source-map/-/source-map-0.5.7.tgz#8a039d2d1021d22d1ea14c80d8ea468ba2ef3fcc"
-source-map@^0.6.1:
+source-map@^0.6.1, source-map@~0.6.1:
version "0.6.1"
resolved "https://registry.yarnpkg.com/source-map/-/source-map-0.6.1.tgz#74722af32e9614e9c287a8d0bbde48b5e2f1a263"
@@ -5896,16 +6082,24 @@ sshpk@^1.7.0:
jsbn "~0.1.0"
tweetnacl "~0.14.0"
-"statuses@>= 1.3.1 < 2", statuses@~1.3.1:
+"statuses@>= 1.3.1 < 2":
version "1.3.1"
resolved "https://registry.yarnpkg.com/statuses/-/statuses-1.3.1.tgz#faf51b9eb74aaef3b3acf4ad5f61abf24cb7b93e"
+statuses@~1.4.0:
+ version "1.4.0"
+ resolved "https://registry.yarnpkg.com/statuses/-/statuses-1.4.0.tgz#bb73d446da2796106efcc1b601a253d6c46bd087"
+
stdout-stream@^1.4.0:
version "1.4.0"
resolved "https://registry.yarnpkg.com/stdout-stream/-/stdout-stream-1.4.0.tgz#a2c7c8587e54d9427ea9edb3ac3f2cd522df378b"
dependencies:
readable-stream "^2.0.1"
+stealthy-require@^1.1.0:
+ version "1.1.1"
+ resolved "https://registry.yarnpkg.com/stealthy-require/-/stealthy-require-1.1.1.tgz#35b09875b4ff49f26a777e509b3090a3226bf24b"
+
stream-browserify@^2.0.1:
version "2.0.1"
resolved "https://registry.yarnpkg.com/stream-browserify/-/stream-browserify-2.0.1.tgz#66266ee5f9bdb9940a4e4514cafb43bb71e5c9db"
@@ -5999,6 +6193,13 @@ strip-json-comments@~2.0.1:
version "2.0.1"
resolved "https://registry.yarnpkg.com/strip-json-comments/-/strip-json-comments-2.0.1.tgz#3c531942e908c2697c0ec344858c286c7ca0a60a"
+style-loader@^0.20.3:
+ version "0.20.3"
+ resolved "https://registry.yarnpkg.com/style-loader/-/style-loader-0.20.3.tgz#ebef06b89dec491bcb1fdb3452e913a6fd1c10c4"
+ dependencies:
+ loader-utils "^1.1.0"
+ schema-utils "^0.4.5"
+
supports-color@^2.0.0:
version "2.0.0"
resolved "https://registry.yarnpkg.com/supports-color/-/supports-color-2.0.0.tgz#535d045ce6b6363fa40117084629995e9df324c7"
@@ -6043,7 +6244,7 @@ symbol-observable@^1.0.3:
version "1.1.0"
resolved "https://registry.yarnpkg.com/symbol-observable/-/symbol-observable-1.1.0.tgz#5c68fd8d54115d9dfb72a84720549222e8db9b32"
-symbol-tree@^3.2.1:
+symbol-tree@^3.2.1, symbol-tree@^3.2.2:
version "3.2.2"
resolved "https://registry.yarnpkg.com/symbol-tree/-/symbol-tree-3.2.2.tgz#ae27db38f660a7ae2e1c3b7d1bc290819b8519e6"
@@ -6137,6 +6338,12 @@ to-fast-properties@^2.0.0:
version "2.0.0"
resolved "https://registry.yarnpkg.com/to-fast-properties/-/to-fast-properties-2.0.0.tgz#dc5e698cbd079265bc73e0377681a4e4e83f616e"
+tough-cookie@>=2.3.3, tough-cookie@^2.3.3:
+ version "2.3.4"
+ resolved "https://registry.yarnpkg.com/tough-cookie/-/tough-cookie-2.3.4.tgz#ec60cee38ac675063ffc97a5c18970578ee83655"
+ dependencies:
+ punycode "^1.4.1"
+
tough-cookie@^2.3.2, tough-cookie@~2.3.3:
version "2.3.3"
resolved "https://registry.yarnpkg.com/tough-cookie/-/tough-cookie-2.3.3.tgz#0b618a5565b6dea90bf3425d04d55edc475a7561"
@@ -6149,6 +6356,12 @@ tough-cookie@~2.3.0:
dependencies:
punycode "^1.4.1"
+tr46@^1.0.0:
+ version "1.0.1"
+ resolved "https://registry.yarnpkg.com/tr46/-/tr46-1.0.1.tgz#a8b13fd6bfd2489519674ccde55ba3693b706d09"
+ dependencies:
+ punycode "^2.1.0"
+
tr46@~0.0.3:
version "0.0.3"
resolved "https://registry.yarnpkg.com/tr46/-/tr46-0.0.3.tgz#8184fd347dac9cdc185992f3a6622e14b9d9ab6a"
@@ -6202,6 +6415,13 @@ type-is@~1.6.15:
media-typer "0.3.0"
mime-types "~2.1.15"
+type-is@~1.6.16:
+ version "1.6.16"
+ resolved "https://registry.yarnpkg.com/type-is/-/type-is-1.6.16.tgz#f89ce341541c672b25ee7ae3c73dee3b2be50194"
+ dependencies:
+ media-typer "0.3.0"
+ mime-types "~2.1.18"
+
typedarray@^0.0.6:
version "0.0.6"
resolved "https://registry.yarnpkg.com/typedarray/-/typedarray-0.0.6.tgz#867ac74e3864187b1d3d47d996a78ec5c8830777"
@@ -6270,9 +6490,9 @@ util@0.10.3, util@^0.10.3:
dependencies:
inherits "2.0.1"
-utils-merge@1.0.0:
- version "1.0.0"
- resolved "https://registry.yarnpkg.com/utils-merge/-/utils-merge-1.0.0.tgz#0294fb922bb9375153541c4f7096231f287c8af8"
+utils-merge@1.0.1:
+ version "1.0.1"
+ resolved "https://registry.yarnpkg.com/utils-merge/-/utils-merge-1.0.1.tgz#9f95710f50a267947b2ccc124741c1028427e713"
uuid@^3.0.0, uuid@^3.1.0:
version "3.1.0"
@@ -6293,6 +6513,10 @@ vary@~1.1.1:
version "1.1.1"
resolved "https://registry.yarnpkg.com/vary/-/vary-1.1.1.tgz#67535ebb694c1d52257457984665323f587e8d37"
+vary@~1.1.2:
+ version "1.1.2"
+ resolved "https://registry.yarnpkg.com/vary/-/vary-1.1.2.tgz#2299f02c6ded30d4a5961b0b9f74524a18f634fc"
+
vendors@^1.0.0:
version "1.0.1"
resolved "https://registry.yarnpkg.com/vendors/-/vendors-1.0.1.tgz#37ad73c8ee417fb3d580e785312307d274847f22"
@@ -6311,6 +6535,12 @@ vm-browserify@0.0.4:
dependencies:
indexof "0.0.1"
+w3c-hr-time@^1.0.1:
+ version "1.0.1"
+ resolved "https://registry.yarnpkg.com/w3c-hr-time/-/w3c-hr-time-1.0.1.tgz#82ac2bff63d950ea9e3189a58a65625fedf19045"
+ dependencies:
+ browser-process-hrtime "^0.1.2"
+
walker@~1.0.5:
version "1.0.7"
resolved "https://registry.yarnpkg.com/walker/-/walker-1.0.7.tgz#2f7f9b8fd10d677262b18a884e28d19618e028fb"
@@ -6342,7 +6572,7 @@ webidl-conversions@^3.0.0:
version "3.0.1"
resolved "https://registry.yarnpkg.com/webidl-conversions/-/webidl-conversions-3.0.1.tgz#24534275e2a7bc6be7bc86611cc16ae0a5654871"
-webidl-conversions@^4.0.0:
+webidl-conversions@^4.0.0, webidl-conversions@^4.0.1, webidl-conversions@^4.0.2:
version "4.0.2"
resolved "https://registry.yarnpkg.com/webidl-conversions/-/webidl-conversions-4.0.2.tgz#a855980b1f0b6b359ba1d5d9fb39ae941faa63ad"
@@ -6380,7 +6610,7 @@ webpack@^3.5.6:
webpack-sources "^1.0.1"
yargs "^8.0.2"
-whatwg-encoding@^1.0.1:
+whatwg-encoding@^1.0.1, whatwg-encoding@^1.0.3:
version "1.0.3"
resolved "https://registry.yarnpkg.com/whatwg-encoding/-/whatwg-encoding-1.0.3.tgz#57c235bc8657e914d24e1a397d3c82daee0a6ba3"
dependencies:
@@ -6390,6 +6620,10 @@ whatwg-fetch@>=0.10.0:
version "2.0.3"
resolved "https://registry.yarnpkg.com/whatwg-fetch/-/whatwg-fetch-2.0.3.tgz#9c84ec2dcf68187ff00bc64e1274b442176e1c84"
+whatwg-fetch@^2.0.4:
+ version "2.0.4"
+ resolved "https://registry.yarnpkg.com/whatwg-fetch/-/whatwg-fetch-2.0.4.tgz#dde6a5df315f9d39991aa17621853d720b85566f"
+
whatwg-url@^4.3.0:
version "4.8.0"
resolved "https://registry.yarnpkg.com/whatwg-url/-/whatwg-url-4.8.0.tgz#d2981aa9148c1e00a41c5a6131166ab4683bbcc0"
@@ -6397,6 +6631,14 @@ whatwg-url@^4.3.0:
tr46 "~0.0.3"
webidl-conversions "^3.0.0"
+whatwg-url@^6.4.0:
+ version "6.4.0"
+ resolved "https://registry.yarnpkg.com/whatwg-url/-/whatwg-url-6.4.0.tgz#08fdf2b9e872783a7a1f6216260a1d66cc722e08"
+ dependencies:
+ lodash.sortby "^4.7.0"
+ tr46 "^1.0.0"
+ webidl-conversions "^4.0.1"
+
whet.extend@~0.9.9:
version "0.9.9"
resolved "https://registry.yarnpkg.com/whet.extend/-/whet.extend-0.9.9.tgz#f877d5bf648c97e5aa542fadc16d6a259b9c11a1"
@@ -6469,10 +6711,21 @@ write@^0.2.1:
dependencies:
mkdirp "^0.5.1"
+ws@^4.0.0:
+ version "4.1.0"
+ resolved "https://registry.yarnpkg.com/ws/-/ws-4.1.0.tgz#a979b5d7d4da68bf54efe0408967c324869a7289"
+ dependencies:
+ async-limiter "~1.0.0"
+ safe-buffer "~5.1.0"
+
xml-name-validator@^2.0.1:
version "2.0.1"
resolved "https://registry.yarnpkg.com/xml-name-validator/-/xml-name-validator-2.0.1.tgz#4d8b8f1eccd3419aa362061becef515e1e559635"
+xml-name-validator@^3.0.0:
+ version "3.0.0"
+ resolved "https://registry.yarnpkg.com/xml-name-validator/-/xml-name-validator-3.0.0.tgz#6ae73e06de4d8c6e47f9fb181f78d648ad457c6a"
+
xtend@^4.0.0, xtend@^4.0.1:
version "4.0.1"
resolved "https://registry.yarnpkg.com/xtend/-/xtend-4.0.1.tgz#a5c6d532be656e23db820efb943a1f04998d63af"