diff --git a/backend/core/permissions.py b/backend/core/permissions.py
index 19b78f0102ffe85879e83c90617c746269c1fafe..3418f6dd13ad69513594f22ef6612261614d72fd 100644
--- a/backend/core/permissions.py
+++ b/backend/core/permissions.py
@@ -1,18 +1,9 @@
 from rest_framework import permissions
 
-from core.custom_annotations import in_groups
-from core.models import Feedback, Student, Submission
+from core.models import Student
 
 
-class StudentRequestOwnData(permissions.BasePermission):
-    def has_object_permission(self, request, view, obj):
-        if in_groups(request.user, ['Students']):
-            student = request.user.student
-            if isinstance(obj, Student):
-                return student == obj
-            elif isinstance(obj, Submission):
-                return student == obj.student
-            elif isinstance(obj, Feedback):
-                return student == obj.of_submission.student
-
-        return False
+class IsStudent(permissions.BasePermission):
+    def has_permission(self, request, view):
+        user = request.user
+        return user.is_authenticated() and isinstance(user.get_associated_user(), Student)
diff --git a/backend/core/serializers.py b/backend/core/serializers.py
index e4c4fa807b5ddb09405953db83885482d63f20c5..c58def5252afb5857ea890a62bb5b31f6f561e72 100644
--- a/backend/core/serializers.py
+++ b/backend/core/serializers.py
@@ -1,7 +1,17 @@
-from django.contrib.auth.models import User
 from rest_framework import serializers
+from core.models import Student, Submission, Feedback, ExamType
 
 from core.models import Feedback, Student, Submission
+=======
+from rest_framework import serializers
+from core.models import Student, Submission, Feedback, ExamType
+
+
+class ExamSerializer(serializers.ModelSerializer):
+    class Meta:
+        model = ExamType
+        fields = ('module_reference', 'total_score', 'pass_score', 'pass_only',)
+>>>>>>> First step towards REST + Vue Student Page
 
 
 class FeedbackSerializer(serializers.ModelSerializer):
@@ -11,15 +21,20 @@ class FeedbackSerializer(serializers.ModelSerializer):
 
 
 class SubmissionSerializer(serializers.ModelSerializer):
-    feedback = FeedbackSerializer()
+    feedback = serializers.ReadOnlyField(source='feedback.text')
+    score = serializers.ReadOnlyField(source='feedback.score')
+    type = serializers.ReadOnlyField(source='type.name')
+    full_score = serializers.ReadOnlyField(source='type.full_score')
 
     class Meta:
         model = Submission
-        fields = ('seen_by_student', 'text', 'type', 'student', 'feedback')
+        fields = ('type', 'text', 'feedback', 'score', 'full_score')
 
 
 class StudentSerializer(serializers.ModelSerializer):
+    name = serializers.ReadOnlyField(source='user.fullname')
     user = serializers.ReadOnlyField(source='user.username')
+    exam = ExamSerializer()
     submissions = SubmissionSerializer(many=True)
 
     class Meta:
diff --git a/backend/core/urls.py b/backend/core/urls.py
index 9f957f393df22fc7d0fa4ac01b637a087e30e1db..962f668183ba4a1bcbd47e69aabc49561a2c2e6e 100644
--- a/backend/core/urls.py
+++ b/backend/core/urls.py
@@ -1,13 +1,15 @@
 from django.conf.urls import url
 from django.contrib.staticfiles.urls import staticfiles_urlpatterns
-from rest_framework.urlpatterns import format_suffix_patterns
+from rest_framework_jwt.views import obtain_jwt_token
 
 from core import views
 
 urlpatterns = [
     url(r'^api/student/$', views.StudentApiView.as_view()),
-    url(r'^api/submission/$', views.SubmissionApiView.as_view()),
-    url(r'^api/feedback/$', views.FeedbackApiView.as_view()),
+    url(r'^api/student/submission/(?P<pk>[0-9]+)$', views.SubmissionApiView.as_view()),
+    url(r'^api/student/submission/(?P<pk>[0-9]+)/feedback/$', views.FeedbackApiView.as_view()),
+
+    url(r'^api-token-auth/', obtain_jwt_token)
 ]
 
 urlpatterns += staticfiles_urlpatterns()
diff --git a/backend/core/views.py b/backend/core/views.py
index 80146573f963e16346c12fd27e1f1b0c01b772fb..5ab7f1ef20219d23f692d3915e7f9c56871bbf19 100644
--- a/backend/core/views.py
+++ b/backend/core/views.py
@@ -1,28 +1,29 @@
-
+from core.serializers import SubmissionSerializer, StudentSerializer, FeedbackSerializer
 from rest_framework.generics import RetrieveAPIView
-
-from core.models import Feedback, Student, Submission
-from core.serializers import (FeedbackSerializer, StudentSerializer,
-                              SubmissionSerializer)
+from core.permissions import IsStudent
 
 
 class StudentApiView(RetrieveAPIView):
+    permission_classes = (IsStudent,)
+
     def get_object(self):
         return self.request.user.student
     serializer_class = StudentSerializer
 
 
 class SubmissionApiView(RetrieveAPIView):
-    def get_object(self):
+    permission_classes = (IsStudent,)
+
+    def get_queryset(self):
         return self.request.user.student.submissions
     serializer_class = SubmissionSerializer
 
 
 class FeedbackApiView(RetrieveAPIView):
+    permission_classes = (IsStudent,)
+
     def get_queryset(self):
         return [submission.feedback for submission in self.request.user.submissions]
     serializer_class = FeedbackSerializer
 
 
-class StudentPageView(RetrieveAPIView):
-    queryset = Student.objects.all()
diff --git a/backend/grady/settings/default.py b/backend/grady/settings/default.py
index 839caa89fb8fb1fae739864256e29b9fd18fbbda..295139848043c5cdd49a4241e3d6f135975a72cb 100644
--- a/backend/grady/settings/default.py
+++ b/backend/grady/settings/default.py
@@ -11,6 +11,7 @@ https://docs.djangoproject.com/en/1.10/ref/settings/
 """
 
 import os
+import datetime
 
 from django.contrib.messages import constants as messages
 
@@ -143,3 +144,19 @@ AUTH_PASSWORD_VALIDATORS = []
 CORS_ORIGIN_WHITELIST = (
     'localhost:8080'
 )
+
+REST_FRAMEWORK = {
+    'DEFAULT_PERMISSION_CLASSES': (
+        'rest_framework.permissions.IsAuthenticated',
+    ),
+    'DEFAULT_AUTHENTICATION_CLASSES': (
+        'rest_framework_jwt.authentication.JSONWebTokenAuthentication',
+        'rest_framework.authentication.SessionAuthentication',
+        'rest_framework.authentication.BasicAuthentication',
+    ),
+}
+
+JWT_AUTH = {
+    'JWT_EXPIRATION_DELTA': datetime.timedelta(seconds=600),
+}
+
diff --git a/backend/requirements.txt b/backend/requirements.txt
index b5f170750297f2f79f68dd732a8371f1cbc4ff72..a6f7f9bd66342e2ef152350adf28a59ea9d4ae2a 100644
--- a/backend/requirements.txt
+++ b/backend/requirements.txt
@@ -1,6 +1,7 @@
 Django~=1.11.3
 django-extensions~=1.7.7
 djangorestframework~=3.6.3
+djangorestframework-jwt~=1.11.0
 django_compressor~=2.1.1
 gunicorn~=19.7.0
 psycopg2~=2.7.1
diff --git a/frontend/src/App.vue b/frontend/src/App.vue
index 20f09c82af20a098c0be0fb79cafbf8247199cc9..11aee7fdf9c9e58f33b670323ac9e2620793f1b1 100644
--- a/frontend/src/App.vue
+++ b/frontend/src/App.vue
@@ -1,23 +1,20 @@
 <template>
   <div id="app">
-    <img src="./assets/logo.png">
     <router-view/>
   </div>
 </template>
 
 <script>
   export default {
-    name: 'app'
+    name: 'app',
+    components: {
+
+    }
 }
 </script>
 
 <style>
 #app {
-  font-family: 'Avenir', Helvetica, Arial, sans-serif;
-  -webkit-font-smoothing: antialiased;
-  -moz-osx-font-smoothing: grayscale;
-  text-align: center;
-  color: #2c3e50;
-  margin-top: 60px;
+
 }
 </style>
diff --git a/frontend/src/assets/brand.png b/frontend/src/assets/brand.png
new file mode 100644
index 0000000000000000000000000000000000000000..5dfdb7913e235b0e63d195afc1d27f1b4ad04c86
Binary files /dev/null and b/frontend/src/assets/brand.png differ
diff --git a/frontend/src/components/HelloWorld.vue b/frontend/src/components/HelloWorld.vue
index 7a4afec5d46561236a571fef2ce5996b47a0d192..0bdb2f3c8e28c00c3a94cfd0e2308baae9cc6060 100644
--- a/frontend/src/components/HelloWorld.vue
+++ b/frontend/src/components/HelloWorld.vue
@@ -1,14 +1,28 @@
 <template>
-  <span>{{msg}}</span>
+  <div>
+    <span>{{msg}}</span>
+    <span>{{token}}</span>
+  </div>
 </template>
 
 <script>
-export default {
-  name: 'HelloWorld',
-  data () {
-    return {
-      msg: 'Welcome to Your Vue.js App'
+  import axios from 'axios'
+
+  export default {
+    name: 'HelloWorld',
+    data () {
+      return {
+        msg: 'Welcome to Your Vue.js App',
+        token: ''
+      }
+    },
+    created: function () {
+      axios.post('http://localhost:8000/api-token-auth/', {
+        username: 'robin',
+        password: 'p'
+      }).then(token => {
+        this.token = token.data.token
+      })
     }
   }
-}
 </script>
diff --git a/frontend/src/components/Login.vue b/frontend/src/components/Login.vue
new file mode 100644
index 0000000000000000000000000000000000000000..0ea4acc6f699578d07e13ef4ecfbcd6ae19eb4d5
--- /dev/null
+++ b/frontend/src/components/Login.vue
@@ -0,0 +1,62 @@
+<template>
+  <div class="mx-auto col-md-4 col-xl-2" id="login">
+    <img src="../assets/brand.png"/>
+    <h2>Log in</h2>
+    <p>Log in to your account to grade stuff!</p>
+    <div class="aler alert-danger" v-if="error">
+      <p>{{ error }}</p>
+    </div>
+    <div class="form-group">
+      <input
+        type="text"
+        class="form-control"
+        placeholder="Enter your username"
+        v-model="credentials.username"
+      />
+    </div>
+    <div class="form-group" @keyup.enter="submit()">
+      <input
+        type="password"
+        class="form-control"
+        placeholder="Enter your password"
+        v-model="credentials.password"
+      />
+    </div>
+    <button class="btn btn-primary" @click="submit()">Access</button>
+  </div>
+</template>
+
+
+<script>
+  export default {
+    name: 'grady-login',
+    data () {
+      return {
+        credentials: {
+          username: '',
+          password: ''
+        },
+        error: ''
+      }
+    },
+    methods: {
+      submit () {
+        const credentials = {
+          username: this.credentials.username,
+          password: this.credentials.password
+        }
+        this.$store.dispatch('getToken', credentials).then(response => {
+          this.$router.push('/student/')
+        })
+      }
+    }
+  }
+</script>
+
+
+<style scoped>
+  #login {
+    text-align: center;
+    margin-top: 10%;
+  }
+</style>
diff --git a/frontend/src/components/student/Base.vue b/frontend/src/components/student/Base.vue
deleted file mode 100644
index 346f7ee00047d77a67a8a0a7b45cd62f64fe524b..0000000000000000000000000000000000000000
--- a/frontend/src/components/student/Base.vue
+++ /dev/null
@@ -1,13 +0,0 @@
-<template>
-
-</template>
-
-
-<script>
-
-</script>
-
-
-<style>
-
-</style>
diff --git a/frontend/src/components/student/ExamInformation.vue b/frontend/src/components/student/ExamInformation.vue
new file mode 100644
index 0000000000000000000000000000000000000000..817cd58c1e42da874890066be1d87409c4d5e4cd
--- /dev/null
+++ b/frontend/src/components/student/ExamInformation.vue
@@ -0,0 +1,29 @@
+<template>
+  <table class="table table-info rounded">
+    <tbody>
+      <tr>
+        <th>Modul</th>
+        <td>{{ exam.module_reference }}</td>
+      </tr>
+      <tr v-if="!exam.pass_only">
+        <th>Pass score</th>
+        <td>{{ exam.pass_score }}</td>
+      </tr>
+      <tr v-else>
+        <th>Pass only!</th>
+      </tr>
+      <tr>
+        <th>Total score</th>
+        <td>{{ exam.total_score }}</td>
+      </tr>
+    </tbody>
+  </table>
+</template>
+
+
+<script>
+  export default {
+    name: 'exam-information',
+    props: ['exam']
+  }
+</script>
diff --git a/frontend/src/components/student/StudentNav.vue b/frontend/src/components/student/StudentNav.vue
new file mode 100644
index 0000000000000000000000000000000000000000..6613a097b7116f3935298a0d4db14d817fe5cabd
--- /dev/null
+++ b/frontend/src/components/student/StudentNav.vue
@@ -0,0 +1,38 @@
+<template>
+  <b-navbar toggleable="md" type="light" variant="light">
+    <b-navbar-toggle target="nav_collapse"></b-navbar-toggle>
+
+    <b-navbar-brand>
+      <img src="../../assets/brand.png" width="30" class="d-inline-block align-top">
+      Grady
+    </b-navbar-brand>
+
+    <b-collapse is-nav id="nav_collapse">
+
+      <b-navbar-nav id="nav-left">
+        <b-nav-item class="active" href="#">Results</b-nav-item>
+        <b-nav-item href="#">Statistics</b-nav-item>
+      </b-navbar-nav>
+
+      <!-- Right aligned nav items -->
+      <b-navbar-nav class="ml-auto">
+        <b-nav-item>{{ this.$store.state.username }}</b-nav-item>
+        <router-link to="/">
+          <b-button class="btn-dark" @click="logout()" >Signout</b-button>
+        </router-link>
+      </b-navbar-nav>
+    </b-collapse>
+  </b-navbar>
+</template>
+
+
+<script>
+  export default {
+    name: 'grady-nav',
+    methods: {
+      logout () {
+        this.$store.dispatch('logout')
+      }
+    }
+  }
+</script>
diff --git a/frontend/src/components/student/StudentPage.vue b/frontend/src/components/student/StudentPage.vue
new file mode 100644
index 0000000000000000000000000000000000000000..b1e9249692fde918bbbfb6f48106301ed3fb62ef
--- /dev/null
+++ b/frontend/src/components/student/StudentPage.vue
@@ -0,0 +1,57 @@
+<template>
+  <div>
+    <grady-nav></grady-nav>
+    <div class="container-fluid">
+      <div class="row justify-content-center my-3">
+        <div class="col-md-3">
+          <h2 class="my-5">Exam Overview</h2>
+          <exam-information v-if="doneLoading" :exam="exam"></exam-information>
+        </div>
+        <div class="col-md-6 offset-md-1" v-if="doneLoading">
+          <h2 class="my-5">Submissions of {{ this.studentData.name }}</h2>
+          <submission-list :submissions="submissions"></submission-list>
+        </div>
+      </div>
+    </div>
+  </div>
+</template>
+
+
+<script>
+  import ax from '@/store/api'
+  import GradyNav from './StudentNav.vue'
+  import SubmissionList from './SubmissionList.vue'
+  import ExamInformation from './ExamInformation.vue'
+
+  export default {
+    components: {
+      ExamInformation,
+      SubmissionList,
+      GradyNav},
+    name: 'student-page',
+    data () {
+      return {
+        studentData: {},
+        doneLoading: false
+      }
+    },
+    created: function () {
+      this.doneLoading = false
+      ax.get('api/student/').then(response => {
+        this.studentData = response.data
+        this.doneLoading = true
+      })
+    },
+    computed: {
+      submissions () {
+        return this.studentData.submissions
+      },
+      exam () {
+        return this.studentData.exam
+      }
+    }
+  }
+</script>
+
+<style scoped>
+</style>
diff --git a/frontend/src/components/student/SubmissionDetail.vue b/frontend/src/components/student/SubmissionDetail.vue
deleted file mode 100644
index 9a7264b44cb929ad25331ddf73d47ce87fedce95..0000000000000000000000000000000000000000
--- a/frontend/src/components/student/SubmissionDetail.vue
+++ /dev/null
@@ -1,12 +0,0 @@
-<template>
-
-</template>
-
-
-<script>
-  export default {
-    computed: {
-
-    }
-  }
-</script>
diff --git a/frontend/src/components/student/SubmissionList.vue b/frontend/src/components/student/SubmissionList.vue
index f4cf766fd04a72f6b2565a5a11f7d872eb802c34..3474bfd527f70ade181d80e319cb6d0ce776d7e6 100644
--- a/frontend/src/components/student/SubmissionList.vue
+++ b/frontend/src/components/student/SubmissionList.vue
@@ -1,33 +1,33 @@
 <template>
-  <ul>
-    <li v-for="sub in submissions">
-      <span>{{sub.type}}</span>
-      <span>{{sub.text}}</span>
-      <span>{{sub.feedback}}</span>
-    </li>
-  </ul>
+  <div class="row my-2 justify-content-center">
+    <b-table hover :items="submissions" :fields="fields"></b-table>
+    <div class="alert alert-info">You reached <b>{{ sumScore }}</b> of <b>{{ sumFullScore }}</b> possible points( {{ pointRatio }}% ).</div>
+  </div>
 </template>
 
+
 <script>
   export default {
-    data: function () {
+    name: 'submission-list',
+    data () {
       return {
-        submissions: []
+        fields: [
+          { key: 'type', sortable: true },
+          { key: 'score', label: 'Score', sortable: true },
+          { key: 'full_score', sortable: true }
+        ]
       }
     },
-    created: function () {
-      this.getSubmissions()
-    },
-    methods: {
-      getSubmissions () {
-        this.$http.get('http://localhost:8000/api/student/1').then(student => {
-          return Promise.all(student.body.submissions.map(id => {
-            return this.$http.get(`http://localhost:8000/api/submission/${id}`)
-          }))
-        }).then(response => {
-          console.log(response)
-          this.submissions = response.map(item => { return item.body })
-        }).catch(console.log.bind(console))
+    props: ['submissions'],
+    computed: {
+      sumScore () {
+        return this.submissions.map(a => a.score).reduce((a, b) => a + b)
+      },
+      sumFullScore () {
+        return this.submissions.map(a => a.full_score).reduce((a, b) => a + b)
+      },
+      pointRatio () {
+        return ((this.sumScore / this.sumFullScore) * 100).toFixed(2)
       }
     }
   }
diff --git a/frontend/src/main.js b/frontend/src/main.js
index 6dca5db2a7163800fa1b10a60694825bc3eb7a21..565189ceedf3e5314ab870b95b6d959192590d07 100644
--- a/frontend/src/main.js
+++ b/frontend/src/main.js
@@ -2,16 +2,20 @@
 // (runtime-only or standalone) has been set in webpack.base.conf with an alias.
 import Vue from 'vue'
 import App from './App'
+import BootstrapVue from 'bootstrap-vue'
 import router from './router'
-import VueResource from 'vue-resource'
+import store from './store/store'
+import 'bootstrap-vue/dist/bootstrap-vue.css'
+import 'bootstrap/dist/css/bootstrap.css'
 
-Vue.use(VueResource)
+Vue.use(BootstrapVue)
 
 Vue.config.productionTip = false
 
 /* eslint-disable no-new */
 new Vue({
   el: '#app',
+  store,
   router,
   template: '<App/>',
   components: { App }
diff --git a/frontend/src/router/index.js b/frontend/src/router/index.js
index b00e372a7bc73b2775a2daa1caf317a10b337709..c29cbc7da105a411223133581fbde9ddec64aace 100644
--- a/frontend/src/router/index.js
+++ b/frontend/src/router/index.js
@@ -1,6 +1,7 @@
 import Vue from 'vue'
 import Router from 'vue-router'
-import SubmissionList from '@/components/student/SubmissionList'
+import Login from '@/components/Login'
+import StudentPage from '@/components/student/StudentPage'
 
 Vue.use(Router)
 
@@ -8,8 +9,13 @@ export default new Router({
   routes: [
     {
       path: '/',
-      name: 'Submissions',
-      component: SubmissionList
+      name: 'grady-login',
+      component: Login
+    },
+    {
+      path: '/student/',
+      name: 'student-page',
+      component: StudentPage
     }
   ]
 })
diff --git a/frontend/src/store/api.js b/frontend/src/store/api.js
index fd2c9786c5d2ecd567f4fcc253ece0423aed7153..368c09c86195ded2f5c97b1199a26e37c4184190 100644
--- a/frontend/src/store/api.js
+++ b/frontend/src/store/api.js
@@ -1,27 +1,7 @@
-import Vue from 'vue'
-import VueResource from 'vue-resource'
+import axios from 'axios'
 
-Vue.use(VueResource)
+var ax = axios.create({
+  baseURL: 'http://localhost:8000/'
+})
 
-export default {
-  get (url, request) {
-    return Vue.http.get(url, request)
-      .then((response) => Promise.resolve(response))
-      .catch((error) => Promise.reject(error))
-  },
-  post (url, request) {
-    return Vue.http.post(url, request)
-      .then((response) => Promise.resolve(response))
-      .catch((error) => Promise.reject(error))
-  },
-  patch (url, request) {
-    return Vue.http.patch(url, request)
-      .then((response) => Promise.resolve(response))
-      .catch((error) => Promise.reject(error))
-  },
-  delete (url, request) {
-    return Vue.http.delete(url, request)
-      .then((response) => Promise.resolve(response))
-      .catch((error) => Promise.reject(error))
-  }
-}
+export default ax
diff --git a/frontend/src/store/store.js b/frontend/src/store/store.js
new file mode 100644
index 0000000000000000000000000000000000000000..150521a07241ce031fa1bd5454e3ba7a9e9f963f
--- /dev/null
+++ b/frontend/src/store/store.js
@@ -0,0 +1,39 @@
+import Vuex from 'vuex'
+import Vue from 'vue'
+import ax from './api'
+
+Vue.use(Vuex)
+
+const store = new Vuex.Store({
+  state: {
+    token: '',
+    loggedIn: false,
+    username: ''
+  },
+  mutations: {
+    'LOGIN': function (state, creds) {
+      state.token = creds.token
+      state.loggedIn = true
+      state.username = creds.username
+    },
+    'LOGOUT': function (state) {
+      state.token = ''
+      state.loggedIn = false
+    }
+  },
+  actions: {
+    async getToken (store, credentials) {
+      const response = await ax.post('api-token-auth/', credentials)
+      store.commit('LOGIN', {
+        token: response.data.token,
+        username: credentials.username
+      })
+      ax.defaults.headers.common['Authorization'] = 'JWT ' + response.data.token
+    },
+    logout (store) {
+      store.commit('LOGOUT')
+    }
+  }
+})
+
+export default store
diff --git a/frontend/yarn.lock b/frontend/yarn.lock
index e96d4143b7d515c3ddf002b6e8e53f7b28d526f9..3d843ede7db636f40806ba4d89597d6c49bdbe2b 100644
--- a/frontend/yarn.lock
+++ b/frontend/yarn.lock
@@ -272,6 +272,13 @@ aws4@^1.2.1, aws4@^1.6.0:
   version "1.6.0"
   resolved "https://registry.yarnpkg.com/aws4/-/aws4-1.6.0.tgz#83ef5ca860b2b32e4a0deedee8c771b9db57471e"
 
+axios@^0.17.0:
+  version "0.17.0"
+  resolved "https://registry.yarnpkg.com/axios/-/axios-0.17.0.tgz#7da747916db803f761651d6091d708789b953c6a"
+  dependencies:
+    follow-redirects "^1.2.3"
+    is-buffer "^1.1.5"
+
 babel-code-frame@^6.11.0, babel-code-frame@^6.16.0, babel-code-frame@^6.22.0, babel-code-frame@^6.26.0:
   version "6.26.0"
   resolved "https://registry.yarnpkg.com/babel-code-frame/-/babel-code-frame-6.26.0.tgz#63fd43f7dc1e3bb7ce35947db8fe369a3f58c74b"
@@ -950,13 +957,15 @@ boom@5.x.x:
   dependencies:
     hoek "4.x.x"
 
-bootstrap-vue@^1.0.0-beta.9:
-  version "1.0.0-beta.9"
-  resolved "https://registry.yarnpkg.com/bootstrap-vue/-/bootstrap-vue-1.0.0-beta.9.tgz#4e0bc5bcb95a90dc3bec7124ea3ddf5cc4c6ffa6"
+bootstrap-vue@^1.0.0:
+  version "1.0.0"
+  resolved "https://registry.yarnpkg.com/bootstrap-vue/-/bootstrap-vue-1.0.0.tgz#65c1d18bce782672c18ba54188e13c2e18725ae0"
   dependencies:
-    bootstrap "^4.0.0-beta"
+    lodash.startcase "^4.4.0"
+    popper.js "^1.12.6"
+    vue-functional-data-merge "^1.0.6"
 
-bootstrap@^4.0.0-beta:
+bootstrap@4.0.0-beta.2:
   version "4.0.0-beta.2"
   resolved "https://registry.yarnpkg.com/bootstrap/-/bootstrap-4.0.0-beta.2.tgz#4d67d2aa2219f062cd90bc1247e6747b9e8fd051"
 
@@ -1673,7 +1682,7 @@ debug@2.6.8:
   dependencies:
     ms "2.0.0"
 
-debug@2.6.9, debug@^2.1.1, debug@^2.2.0, debug@^2.6.8:
+debug@2.6.9, debug@^2.1.1, debug@^2.2.0, debug@^2.6.8, debug@^2.6.9:
   version "2.6.9"
   resolved "https://registry.yarnpkg.com/debug/-/debug-2.6.9.tgz#5d128515df134ff327e90a4c93f4e077a536341f"
   dependencies:
@@ -1683,12 +1692,6 @@ decamelize@^1.0.0, decamelize@^1.1.1, decamelize@^1.1.2:
   version "1.2.0"
   resolved "https://registry.yarnpkg.com/decamelize/-/decamelize-1.2.0.tgz#f6534d15148269b20352e7bee26f501f9a191290"
 
-decompress-response@^3.2.0:
-  version "3.3.0"
-  resolved "https://registry.yarnpkg.com/decompress-response/-/decompress-response-3.3.0.tgz#80a4dd323748384bfa248083622aedec982adff3"
-  dependencies:
-    mimic-response "^1.0.0"
-
 deep-eql@^3.0.0:
   version "3.0.1"
   resolved "https://registry.yarnpkg.com/deep-eql/-/deep-eql-3.0.1.tgz#dfc9404400ad1c8fe023e7da1df1c147c4b444df"
@@ -1852,10 +1855,6 @@ domutils@^1.5.1:
     dom-serializer "0"
     domelementtype "1"
 
-duplexer3@^0.1.4:
-  version "0.1.4"
-  resolved "https://registry.yarnpkg.com/duplexer3/-/duplexer3-0.1.4.tgz#ee01dd1cac0ed3cbc7fdbea37dc0a8f1ce002ce2"
-
 duplexer@^0.1.1:
   version "0.1.1"
   resolved "https://registry.yarnpkg.com/duplexer/-/duplexer-0.1.1.tgz#ace6ff808c1ce66b57d1ebf97977acb02334cfc1"
@@ -2480,6 +2479,12 @@ flatten@^1.0.2:
   version "1.0.2"
   resolved "https://registry.yarnpkg.com/flatten/-/flatten-1.0.2.tgz#dae46a9d78fbe25292258cc1e780a41d95c03782"
 
+follow-redirects@^1.2.3:
+  version "1.2.5"
+  resolved "https://registry.yarnpkg.com/follow-redirects/-/follow-redirects-1.2.5.tgz#ffd3e14cbdd5eaa72f61b6368c1f68516c2a26cc"
+  dependencies:
+    debug "^2.6.9"
+
 for-in@^1.0.1:
   version "1.0.2"
   resolved "https://registry.yarnpkg.com/for-in/-/for-in-1.0.2.tgz#81068d295a8142ec0ac726c6e2200c30fb6d5e80"
@@ -2685,25 +2690,6 @@ globby@^5.0.0:
     pify "^2.0.0"
     pinkie-promise "^2.0.0"
 
-got@^7.0.0:
-  version "7.1.0"
-  resolved "https://registry.yarnpkg.com/got/-/got-7.1.0.tgz#05450fd84094e6bbea56f451a43a9c289166385a"
-  dependencies:
-    decompress-response "^3.2.0"
-    duplexer3 "^0.1.4"
-    get-stream "^3.0.0"
-    is-plain-obj "^1.1.0"
-    is-retry-allowed "^1.0.0"
-    is-stream "^1.0.0"
-    isurl "^1.0.0-alpha5"
-    lowercase-keys "^1.0.0"
-    p-cancelable "^0.3.0"
-    p-timeout "^1.1.1"
-    safe-buffer "^5.0.1"
-    timed-out "^4.0.0"
-    url-parse-lax "^1.0.0"
-    url-to-options "^1.0.1"
-
 graceful-fs@^4.1.2, graceful-fs@^4.1.6, graceful-fs@^4.1.9:
   version "4.1.11"
   resolved "https://registry.yarnpkg.com/graceful-fs/-/graceful-fs-4.1.11.tgz#0e8bdfe4d1ddb8854d64e04ea7c00e2a026e5658"
@@ -2778,16 +2764,6 @@ has-flag@^2.0.0:
   version "2.0.0"
   resolved "https://registry.yarnpkg.com/has-flag/-/has-flag-2.0.0.tgz#e8207af1cc7b30d446cc70b734b5e8be18f88d51"
 
-has-symbol-support-x@^1.4.1:
-  version "1.4.1"
-  resolved "https://registry.yarnpkg.com/has-symbol-support-x/-/has-symbol-support-x-1.4.1.tgz#66ec2e377e0c7d7ccedb07a3a84d77510ff1bc4c"
-
-has-to-string-tag-x@^1.2.0:
-  version "1.4.1"
-  resolved "https://registry.yarnpkg.com/has-to-string-tag-x/-/has-to-string-tag-x-1.4.1.tgz#a045ab383d7b4b2012a00148ab0aa5f290044d4d"
-  dependencies:
-    has-symbol-support-x "^1.4.1"
-
 has-unicode@^2.0.0:
   version "2.0.1"
   resolved "https://registry.yarnpkg.com/has-unicode/-/has-unicode-2.0.1.tgz#e0e6fe6a28cf51138855e086d1691e771de2a8b9"
@@ -3185,10 +3161,6 @@ is-number@^3.0.0:
   dependencies:
     kind-of "^3.0.2"
 
-is-object@^1.0.1:
-  version "1.0.1"
-  resolved "https://registry.yarnpkg.com/is-object/-/is-object-1.0.1.tgz#8952688c5ec2ffd6b03ecc85e769e02903083470"
-
 is-path-cwd@^1.0.0:
   version "1.0.0"
   resolved "https://registry.yarnpkg.com/is-path-cwd/-/is-path-cwd-1.0.0.tgz#d225ec23132e89edd38fda767472e62e65f1106d"
@@ -3205,7 +3177,7 @@ is-path-inside@^1.0.0:
   dependencies:
     path-is-inside "^1.0.1"
 
-is-plain-obj@^1.0.0, is-plain-obj@^1.1.0:
+is-plain-obj@^1.0.0:
   version "1.1.0"
   resolved "https://registry.yarnpkg.com/is-plain-obj/-/is-plain-obj-1.1.0.tgz#71a50c8429dfca773c92a390a4a03b39fcd51d3e"
 
@@ -3227,11 +3199,7 @@ is-resolvable@^1.0.0:
   dependencies:
     tryit "^1.0.1"
 
-is-retry-allowed@^1.0.0:
-  version "1.1.0"
-  resolved "https://registry.yarnpkg.com/is-retry-allowed/-/is-retry-allowed-1.1.0.tgz#11a060568b67339444033d0125a61a20d564fb34"
-
-is-stream@^1.0.0, is-stream@^1.0.1, is-stream@^1.1.0:
+is-stream@^1.0.1, is-stream@^1.1.0:
   version "1.1.0"
   resolved "https://registry.yarnpkg.com/is-stream/-/is-stream-1.1.0.tgz#12d4a3dd4e68e0b79ceb8dbc84173ae80d91ca44"
 
@@ -3318,13 +3286,6 @@ istanbul@^0.4.0:
     which "^1.1.1"
     wordwrap "^1.0.0"
 
-isurl@^1.0.0-alpha5:
-  version "1.0.0"
-  resolved "https://registry.yarnpkg.com/isurl/-/isurl-1.0.0.tgz#b27f4f49f3cdaa3ea44a0a5b7f3462e6edc39d67"
-  dependencies:
-    has-to-string-tag-x "^1.2.0"
-    is-object "^1.0.1"
-
 js-base64@^2.1.9:
   version "2.3.2"
   resolved "https://registry.yarnpkg.com/js-base64/-/js-base64-2.3.2.tgz#a79a923666372b580f8e27f51845c6f7e8fbfbaf"
@@ -3672,6 +3633,10 @@ lodash.memoize@^4.1.2:
   version "4.1.2"
   resolved "https://registry.yarnpkg.com/lodash.memoize/-/lodash.memoize-4.1.2.tgz#bcc6c49a42a2840ed997f323eada5ecd182e0bfe"
 
+lodash.startcase@^4.4.0:
+  version "4.4.0"
+  resolved "https://registry.yarnpkg.com/lodash.startcase/-/lodash.startcase-4.4.0.tgz#9436e34ed26093ed7ffae1936144350915d9add8"
+
 lodash.uniq@^4.5.0:
   version "4.5.0"
   resolved "https://registry.yarnpkg.com/lodash.uniq/-/lodash.uniq-4.5.0.tgz#d0225373aeb652adc1bc82e4945339a842754773"
@@ -3726,10 +3691,6 @@ lower-case@^1.1.1:
   version "1.1.4"
   resolved "https://registry.yarnpkg.com/lower-case/-/lower-case-1.1.4.tgz#9a2cabd1b9e8e0ae993a4bf7d5875c39c42e8eac"
 
-lowercase-keys@^1.0.0:
-  version "1.0.0"
-  resolved "https://registry.yarnpkg.com/lowercase-keys/-/lowercase-keys-1.0.0.tgz#4e3366b39e7f5457e35f1324bdf6f88d0bfc7306"
-
 lru-cache@2.2.x:
   version "2.2.4"
   resolved "https://registry.yarnpkg.com/lru-cache/-/lru-cache-2.2.4.tgz#6c658619becf14031d0d0b594b16042ce4dc063d"
@@ -3853,10 +3814,6 @@ mimic-fn@^1.0.0:
   version "1.1.0"
   resolved "https://registry.yarnpkg.com/mimic-fn/-/mimic-fn-1.1.0.tgz#e667783d92e89dbd342818b5230b9d62a672ad18"
 
-mimic-response@^1.0.0:
-  version "1.0.0"
-  resolved "https://registry.yarnpkg.com/mimic-response/-/mimic-response-1.0.0.tgz#df3d3652a73fded6b9b0b24146e6fd052353458e"
-
 minimalistic-assert@^1.0.0:
   version "1.0.0"
   resolved "https://registry.yarnpkg.com/minimalistic-assert/-/minimalistic-assert-1.0.0.tgz#702be2dda6b37f4836bcb3f5db56641b64a1d3d3"
@@ -4206,10 +4163,6 @@ osenv@^0.1.4:
     os-homedir "^1.0.0"
     os-tmpdir "^1.0.0"
 
-p-cancelable@^0.3.0:
-  version "0.3.0"
-  resolved "https://registry.yarnpkg.com/p-cancelable/-/p-cancelable-0.3.0.tgz#b9e123800bcebb7ac13a479be195b507b98d30fa"
-
 p-finally@^1.0.0:
   version "1.0.0"
   resolved "https://registry.yarnpkg.com/p-finally/-/p-finally-1.0.0.tgz#3fbcfb15b899a44123b34b6dcc18b724336a2cae"
@@ -4224,12 +4177,6 @@ p-locate@^2.0.0:
   dependencies:
     p-limit "^1.1.0"
 
-p-timeout@^1.1.1:
-  version "1.2.0"
-  resolved "https://registry.yarnpkg.com/p-timeout/-/p-timeout-1.2.0.tgz#9820f99434c5817868b4f34809ee5291660d5b6c"
-  dependencies:
-    p-finally "^1.0.0"
-
 pako@~0.2.0:
   version "0.2.9"
   resolved "https://registry.yarnpkg.com/pako/-/pako-0.2.9.tgz#f3f7522f4ef782348da8161bad9ecfd51bf83a75"
@@ -4415,6 +4362,10 @@ pluralize@^1.2.1:
   version "1.2.1"
   resolved "https://registry.yarnpkg.com/pluralize/-/pluralize-1.2.1.tgz#d1a21483fd22bb41e58a12fa3421823140897c45"
 
+popper.js@^1.12.6:
+  version "1.12.6"
+  resolved "https://registry.yarnpkg.com/popper.js/-/popper.js-1.12.6.tgz#91e12a97b07815258b76915d64044e8ac053d426"
+
 portfinder@^1.0.13:
   version "1.0.13"
   resolved "https://registry.yarnpkg.com/portfinder/-/portfinder-1.0.13.tgz#bb32ecd87c27104ae6ee44b5a3ccbf0ebb1aede9"
@@ -4696,7 +4647,7 @@ prelude-ls@~1.1.2:
   version "1.1.2"
   resolved "https://registry.yarnpkg.com/prelude-ls/-/prelude-ls-1.1.2.tgz#21932a549f5e52ffd9a827f570e04be62a97da54"
 
-prepend-http@^1.0.0, prepend-http@^1.0.1:
+prepend-http@^1.0.0:
   version "1.0.4"
   resolved "https://registry.yarnpkg.com/prepend-http/-/prepend-http-1.0.4.tgz#d4f4562b0ce3696e41ac52d0e002e57a635dc6dc"
 
@@ -5624,10 +5575,6 @@ time-stamp@^2.0.0:
   version "2.0.0"
   resolved "https://registry.yarnpkg.com/time-stamp/-/time-stamp-2.0.0.tgz#95c6a44530e15ba8d6f4a3ecb8c3a3fac46da357"
 
-timed-out@^4.0.0:
-  version "4.0.1"
-  resolved "https://registry.yarnpkg.com/timed-out/-/timed-out-4.0.1.tgz#f32eacac5a175bea25d7fab565ab3ed8741ef56f"
-
 timers-browserify@^2.0.2:
   version "2.0.4"
   resolved "https://registry.yarnpkg.com/timers-browserify/-/timers-browserify-2.0.4.tgz#96ca53f4b794a5e7c0e1bd7cc88a372298fa01e6"
@@ -5788,16 +5735,6 @@ url-loader@^0.5.8:
     loader-utils "^1.0.2"
     mime "1.3.x"
 
-url-parse-lax@^1.0.0:
-  version "1.0.0"
-  resolved "https://registry.yarnpkg.com/url-parse-lax/-/url-parse-lax-1.0.0.tgz#7af8f303645e9bd79a272e7a14ac68bc0609da73"
-  dependencies:
-    prepend-http "^1.0.1"
-
-url-to-options@^1.0.1:
-  version "1.0.1"
-  resolved "https://registry.yarnpkg.com/url-to-options/-/url-to-options-1.0.1.tgz#1505a03a289a48cbd7a434efbaeec5055f5633a9"
-
 url@^0.11.0:
   version "0.11.0"
   resolved "https://registry.yarnpkg.com/url/-/url-0.11.0.tgz#3838e97cfc60521eb73c525a8e55bfdd9e2e28f1"
@@ -5877,6 +5814,10 @@ void-elements@^2.0.0:
   version "2.0.1"
   resolved "https://registry.yarnpkg.com/void-elements/-/void-elements-2.0.1.tgz#c066afb582bb1cb4128d60ea92392e94d5e9dbec"
 
+vue-functional-data-merge@^1.0.6:
+  version "1.0.6"
+  resolved "https://registry.yarnpkg.com/vue-functional-data-merge/-/vue-functional-data-merge-1.0.6.tgz#cde4f0cf3f251f7f0196341156d2c936cca63d40"
+
 vue-hot-reload-api@^2.2.0:
   version "2.2.0"
   resolved "https://registry.yarnpkg.com/vue-hot-reload-api/-/vue-hot-reload-api-2.2.0.tgz#9a21b35ced3634434a43ee80efb7350ea8fb206d"
@@ -5899,12 +5840,6 @@ vue-loader@^13.3.0:
     vue-style-loader "^3.0.0"
     vue-template-es2015-compiler "^1.6.0"
 
-vue-resource@^1.3.4:
-  version "1.3.4"
-  resolved "https://registry.yarnpkg.com/vue-resource/-/vue-resource-1.3.4.tgz#9fc0bdf6a2f5cab430129fc99d347b3deae7b099"
-  dependencies:
-    got "^7.0.0"
-
 vue-router@^3.0.1:
   version "3.0.1"
   resolved "https://registry.yarnpkg.com/vue-router/-/vue-router-3.0.1.tgz#d9b05ad9c7420ba0f626d6500d693e60092cc1e9"