Sendya 6 years ago
parent
commit
1cf6572c4c

+ 3 - 0
package.json

@@ -8,11 +8,14 @@
     "lint": "vue-cli-service lint"
   },
   "dependencies": {
+    "@antv/data-set": "^0.8.9",
     "ant-design-vue": "^1.0.3",
     "axios": "^0.18.0",
     "js-cookie": "^2.2.0",
+    "md5": "^2.2.1",
     "moment": "^2.22.2",
     "nprogress": "^0.2.0",
+    "viser-vue": "^2.3.0",
     "vue": "^2.5.17",
     "vue-router": "^3.0.1",
     "vuex": "^3.0.1"

BIN
public/favicon.ico


+ 1 - 1
public/index.html

@@ -4,7 +4,7 @@
     <meta charset="utf-8">
     <meta http-equiv="X-UA-Compatible" content="IE=edge">
     <meta name="viewport" content="width=device-width,initial-scale=1.0">
-    <link rel="icon" href="<%= BASE_URL %>favicon.ico">
+    <link rel="icon" href="<%= BASE_URL %>logo.png">
     <title>Ant Design Pro</title>
   </head>
   <body>

BIN
public/logo.png


+ 7 - 1
src/App.vue

@@ -2,4 +2,10 @@
   <div id="app">
     <router-view/>
   </div>
-</template>
+</template>
+
+<style>
+  #app {
+    height: 100%;
+  }
+</style>

+ 10 - 0
src/api/index.js

@@ -0,0 +1,10 @@
+const api = {
+    Login: '/auth/login',
+    Logout: '/auth/logout',
+    ForgePassword: '/auth/forge-password',
+    Register: '/auth/register',
+    SendSms: '/account/sms',
+    // get my info
+    UserInfo: '/user/info'
+}
+export default api

+ 13 - 5
src/api/login.js

@@ -1,13 +1,21 @@
 import { axios } from '@/utils/request'
 
-export function login(username, password) {
+/**
+ * login func
+ * parameter: {
+ *     username: '',
+ *     password: '',
+ *     remember_me: true,
+ *     captcha: '12345'
+ * }
+ * @param parameter
+ * @returns {*}
+ */
+export function login(parameter) {
   return axios({
     url: '/auth/login',
     method: 'post',
-    data: {
-      username,
-      password
-    }
+    data: parameter
   })
 }
 

+ 69 - 0
src/assets/background.svg

@@ -0,0 +1,69 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<svg width="1361px" height="609px" viewBox="0 0 1361 609" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
+    <!-- Generator: Sketch 46.2 (44496) - http://www.bohemiancoding.com/sketch -->
+    <title>Group 21</title>
+    <desc>Created with Sketch.</desc>
+    <defs></defs>
+    <g id="Ant-Design-Pro-3.0" stroke="none" stroke-width="1" fill="none" fill-rule="evenodd">
+        <g id="账户密码登录-校验" transform="translate(-79.000000, -82.000000)">
+            <g id="Group-21" transform="translate(77.000000, 73.000000)">
+                <g id="Group-18" opacity="0.8" transform="translate(74.901416, 569.699158) rotate(-7.000000) translate(-74.901416, -569.699158) translate(4.901416, 525.199158)">
+                    <ellipse id="Oval-11" fill="#CFDAE6" opacity="0.25" cx="63.5748792" cy="32.468367" rx="21.7830479" ry="21.766008"></ellipse>
+                    <ellipse id="Oval-3" fill="#CFDAE6" opacity="0.599999964" cx="5.98746479" cy="13.8668601" rx="5.2173913" ry="5.21330997"></ellipse>
+                    <path d="M38.1354514,88.3520215 C43.8984227,88.3520215 48.570234,83.6838647 48.570234,77.9254015 C48.570234,72.1669383 43.8984227,67.4987816 38.1354514,67.4987816 C32.3724801,67.4987816 27.7006688,72.1669383 27.7006688,77.9254015 C27.7006688,83.6838647 32.3724801,88.3520215 38.1354514,88.3520215 Z" id="Oval-3-Copy" fill="#CFDAE6" opacity="0.45"></path>
+                    <path d="M64.2775582,33.1704963 L119.185836,16.5654915" id="Path-12" stroke="#CFDAE6" stroke-width="1.73913043" stroke-linecap="round" stroke-linejoin="round"></path>
+                    <path d="M42.1431708,26.5002681 L7.71190162,14.5640702" id="Path-16" stroke="#E0B4B7" stroke-width="0.702678964" opacity="0.7" stroke-linecap="round" stroke-linejoin="round" stroke-dasharray="1.405357899873153,2.108036953469981"></path>
+                    <path d="M63.9262187,33.521561 L43.6721326,69.3250951" id="Path-15" stroke="#BACAD9" stroke-width="0.702678964" stroke-linecap="round" stroke-linejoin="round" stroke-dasharray="1.405357899873153,2.108036953469981"></path>
+                    <g id="Group-17" transform="translate(126.850922, 13.543654) rotate(30.000000) translate(-126.850922, -13.543654) translate(117.285705, 4.381889)" fill="#CFDAE6">
+                        <ellipse id="Oval-4" opacity="0.45" cx="9.13482653" cy="9.12768076" rx="9.13482653" ry="9.12768076"></ellipse>
+                        <path d="M18.2696531,18.2553615 C18.2696531,13.2142826 14.1798519,9.12768076 9.13482653,9.12768076 C4.08980114,9.12768076 0,13.2142826 0,18.2553615 L18.2696531,18.2553615 Z" id="Oval-4" transform="translate(9.134827, 13.691521) scale(-1, -1) translate(-9.134827, -13.691521) "></path>
+                    </g>
+                </g>
+                <g id="Group-14" transform="translate(216.294700, 123.725600) rotate(-5.000000) translate(-216.294700, -123.725600) translate(106.294700, 35.225600)">
+                    <ellipse id="Oval-2" fill="#CFDAE6" opacity="0.25" cx="29.1176471" cy="29.1402439" rx="29.1176471" ry="29.1402439"></ellipse>
+                    <ellipse id="Oval-2" fill="#CFDAE6" opacity="0.3" cx="29.1176471" cy="29.1402439" rx="21.5686275" ry="21.5853659"></ellipse>
+                    <ellipse id="Oval-2-Copy" stroke="#CFDAE6" opacity="0.4" cx="179.019608" cy="138.146341" rx="23.7254902" ry="23.7439024"></ellipse>
+                    <ellipse id="Oval-2" fill="#BACAD9" opacity="0.5" cx="29.1176471" cy="29.1402439" rx="10.7843137" ry="10.7926829"></ellipse>
+                    <path d="M29.1176471,39.9329268 L29.1176471,18.347561 C23.1616351,18.347561 18.3333333,23.1796097 18.3333333,29.1402439 C18.3333333,35.1008781 23.1616351,39.9329268 29.1176471,39.9329268 Z" id="Oval-2" fill="#BACAD9"></path>
+                    <g id="Group-9" opacity="0.45" transform="translate(172.000000, 131.000000)" fill="#E6A1A6">
+                        <ellipse id="Oval-2-Copy-2" cx="7.01960784" cy="7.14634146" rx="6.47058824" ry="6.47560976"></ellipse>
+                        <path d="M0.549019608,13.6219512 C4.12262681,13.6219512 7.01960784,10.722722 7.01960784,7.14634146 C7.01960784,3.56996095 4.12262681,0.670731707 0.549019608,0.670731707 L0.549019608,13.6219512 Z" id="Oval-2-Copy-2" transform="translate(3.784314, 7.146341) scale(-1, 1) translate(-3.784314, -7.146341) "></path>
+                    </g>
+                    <ellipse id="Oval-10" fill="#CFDAE6" cx="218.382353" cy="138.685976" rx="1.61764706" ry="1.61890244"></ellipse>
+                    <ellipse id="Oval-10-Copy-2" fill="#E0B4B7" opacity="0.35" cx="179.558824" cy="175.381098" rx="1.61764706" ry="1.61890244"></ellipse>
+                    <ellipse id="Oval-10-Copy" fill="#E0B4B7" opacity="0.35" cx="180.098039" cy="102.530488" rx="2.15686275" ry="2.15853659"></ellipse>
+                    <path d="M28.9985381,29.9671598 L171.151018,132.876024" id="Path-11" stroke="#CFDAE6" opacity="0.8"></path>
+                </g>
+                <g id="Group-10" opacity="0.799999952" transform="translate(1054.100635, 36.659317) rotate(-11.000000) translate(-1054.100635, -36.659317) translate(1026.600635, 4.659317)">
+                    <ellipse id="Oval-7" stroke="#CFDAE6" stroke-width="0.941176471" cx="43.8135593" cy="32" rx="11.1864407" ry="11.2941176"></ellipse>
+                    <g id="Group-12" transform="translate(34.596774, 23.111111)" fill="#BACAD9">
+                        <ellipse id="Oval-7" opacity="0.45" cx="9.18534718" cy="8.88888889" rx="8.47457627" ry="8.55614973"></ellipse>
+                        <path d="M9.18534718,17.4450386 C13.8657264,17.4450386 17.6599235,13.6143199 17.6599235,8.88888889 C17.6599235,4.16345787 13.8657264,0.332739156 9.18534718,0.332739156 L9.18534718,17.4450386 Z" id="Oval-7"></path>
+                    </g>
+                    <path d="M34.6597385,24.809694 L5.71666084,4.76878945" id="Path-2" stroke="#CFDAE6" stroke-width="0.941176471"></path>
+                    <ellipse id="Oval" stroke="#CFDAE6" stroke-width="0.941176471" cx="3.26271186" cy="3.29411765" rx="3.26271186" ry="3.29411765"></ellipse>
+                    <ellipse id="Oval-Copy" fill="#F7E1AD" cx="2.79661017" cy="61.1764706" rx="2.79661017" ry="2.82352941"></ellipse>
+                    <path d="M34.6312443,39.2922712 L5.06366663,59.785082" id="Path-10" stroke="#CFDAE6" stroke-width="0.941176471"></path>
+                </g>
+                <g id="Group-19" opacity="0.33" transform="translate(1282.537219, 446.502867) rotate(-10.000000) translate(-1282.537219, -446.502867) translate(1142.537219, 327.502867)">
+                    <g id="Group-17" transform="translate(141.333539, 104.502742) rotate(275.000000) translate(-141.333539, -104.502742) translate(129.333539, 92.502742)" fill="#BACAD9">
+                        <circle id="Oval-4" opacity="0.45" cx="11.6666667" cy="11.6666667" r="11.6666667"></circle>
+                        <path d="M23.3333333,23.3333333 C23.3333333,16.8900113 18.1099887,11.6666667 11.6666667,11.6666667 C5.22334459,11.6666667 0,16.8900113 0,23.3333333 L23.3333333,23.3333333 Z" id="Oval-4" transform="translate(11.666667, 17.500000) scale(-1, -1) translate(-11.666667, -17.500000) "></path>
+                    </g>
+                    <circle id="Oval-5-Copy-6" fill="#CFDAE6" cx="201.833333" cy="87.5" r="5.83333333"></circle>
+                    <path d="M143.5,88.8126685 L155.070501,17.6038544" id="Path-17" stroke="#BACAD9" stroke-width="1.16666667"></path>
+                    <path d="M17.5,37.3333333 L127.466252,97.6449735" id="Path-18" stroke="#BACAD9" stroke-width="1.16666667"></path>
+                    <polyline id="Path-19" stroke="#CFDAE6" stroke-width="1.16666667" points="143.902597 120.302281 174.935455 231.571342 38.5 147.510847 126.366941 110.833333"></polyline>
+                    <path d="M159.833333,99.7453842 L195.416667,89.25" id="Path-20" stroke="#E0B4B7" stroke-width="1.16666667" opacity="0.6"></path>
+                    <path d="M205.333333,82.1372105 L238.719406,36.1666667" id="Path-24" stroke="#BACAD9" stroke-width="1.16666667"></path>
+                    <path d="M266.723424,132.231988 L207.083333,90.4166667" id="Path-25" stroke="#CFDAE6" stroke-width="1.16666667"></path>
+                    <circle id="Oval-5" fill="#C1D1E0" cx="156.916667" cy="8.75" r="8.75"></circle>
+                    <circle id="Oval-5-Copy-3" fill="#C1D1E0" cx="39.0833333" cy="148.75" r="5.25"></circle>
+                    <circle id="Oval-5-Copy-2" fill-opacity="0.6" fill="#D1DEED" cx="8.75" cy="33.25" r="8.75"></circle>
+                    <circle id="Oval-5-Copy-4" fill-opacity="0.6" fill="#D1DEED" cx="243.833333" cy="30.3333333" r="5.83333333"></circle>
+                    <circle id="Oval-5-Copy-5" fill="#E0B4B7" cx="175.583333" cy="232.75" r="5.25"></circle>
+                </g>
+            </g>
+        </g>
+    </g>
+</svg>

BIN
src/assets/logo.png


+ 43 - 0
src/assets/logo.svg

@@ -0,0 +1,43 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<svg width="200px" height="200px" viewBox="0 0 200 200" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
+    <!-- Generator: Sketch 47.1 (45422) - http://www.bohemiancoding.com/sketch -->
+    <title>Group 28 Copy 5</title>
+    <desc>Created with Sketch.</desc>
+    <defs>
+        <linearGradient x1="62.1023273%" y1="0%" x2="108.19718%" y2="37.8635764%" id="linearGradient-1">
+            <stop stop-color="#4285EB" offset="0%"></stop>
+            <stop stop-color="#2EC7FF" offset="100%"></stop>
+        </linearGradient>
+        <linearGradient x1="69.644116%" y1="0%" x2="54.0428975%" y2="108.456714%" id="linearGradient-2">
+            <stop stop-color="#29CDFF" offset="0%"></stop>
+            <stop stop-color="#148EFF" offset="37.8600687%"></stop>
+            <stop stop-color="#0A60FF" offset="100%"></stop>
+        </linearGradient>
+        <linearGradient x1="69.6908165%" y1="-12.9743587%" x2="16.7228981%" y2="117.391248%" id="linearGradient-3">
+            <stop stop-color="#FA816E" offset="0%"></stop>
+            <stop stop-color="#F74A5C" offset="41.472606%"></stop>
+            <stop stop-color="#F51D2C" offset="100%"></stop>
+        </linearGradient>
+        <linearGradient x1="68.1279872%" y1="-35.6905737%" x2="30.4400914%" y2="114.942679%" id="linearGradient-4">
+            <stop stop-color="#FA8E7D" offset="0%"></stop>
+            <stop stop-color="#F74A5C" offset="51.2635191%"></stop>
+            <stop stop-color="#F51D2C" offset="100%"></stop>
+        </linearGradient>
+    </defs>
+    <g id="Page-1" stroke="none" stroke-width="1" fill="none" fill-rule="evenodd">
+        <g id="logo" transform="translate(-20.000000, -20.000000)">
+            <g id="Group-28-Copy-5" transform="translate(20.000000, 20.000000)">
+                <g id="Group-27-Copy-3">
+                    <g id="Group-25" fill-rule="nonzero">
+                        <g id="2">
+                            <path d="M91.5880863,4.17652823 L4.17996544,91.5127728 C-0.519240605,96.2081146 -0.519240605,103.791885 4.17996544,108.487227 L91.5880863,195.823472 C96.2872923,200.518814 103.877304,200.518814 108.57651,195.823472 L145.225487,159.204632 C149.433969,154.999611 149.433969,148.181924 145.225487,143.976903 C141.017005,139.771881 134.193707,139.771881 129.985225,143.976903 L102.20193,171.737352 C101.032305,172.906015 99.2571609,172.906015 98.0875359,171.737352 L28.285908,101.993122 C27.1162831,100.824459 27.1162831,99.050775 28.285908,97.8821118 L98.0875359,28.1378823 C99.2571609,26.9692191 101.032305,26.9692191 102.20193,28.1378823 L129.985225,55.8983314 C134.193707,60.1033528 141.017005,60.1033528 145.225487,55.8983314 C149.433969,51.69331 149.433969,44.8756232 145.225487,40.6706018 L108.58055,4.05574592 C103.862049,-0.537986846 96.2692618,-0.500797906 91.5880863,4.17652823 Z" id="Shape" fill="url(#linearGradient-1)"></path>
+                            <path d="M91.5880863,4.17652823 L4.17996544,91.5127728 C-0.519240605,96.2081146 -0.519240605,103.791885 4.17996544,108.487227 L91.5880863,195.823472 C96.2872923,200.518814 103.877304,200.518814 108.57651,195.823472 L145.225487,159.204632 C149.433969,154.999611 149.433969,148.181924 145.225487,143.976903 C141.017005,139.771881 134.193707,139.771881 129.985225,143.976903 L102.20193,171.737352 C101.032305,172.906015 99.2571609,172.906015 98.0875359,171.737352 L28.285908,101.993122 C27.1162831,100.824459 27.1162831,99.050775 28.285908,97.8821118 L98.0875359,28.1378823 C100.999864,25.6271836 105.751642,20.541824 112.729652,19.3524487 C117.915585,18.4685261 123.585219,20.4140239 129.738554,25.1889424 C125.624663,21.0784292 118.571995,14.0340304 108.58055,4.05574592 C103.862049,-0.537986846 96.2692618,-0.500797906 91.5880863,4.17652823 Z" id="Shape" fill="url(#linearGradient-2)"></path>
+                        </g>
+                        <path d="M153.685633,135.854579 C157.894115,140.0596 164.717412,140.0596 168.925894,135.854579 L195.959977,108.842726 C200.659183,104.147384 200.659183,96.5636133 195.960527,91.8688194 L168.690777,64.7181159 C164.472332,60.5180858 157.646868,60.5241425 153.435895,64.7316526 C149.227413,68.936674 149.227413,75.7543607 153.435895,79.9593821 L171.854035,98.3623765 C173.02366,99.5310396 173.02366,101.304724 171.854035,102.473387 L153.685633,120.626849 C149.47715,124.83187 149.47715,131.649557 153.685633,135.854579 Z" id="Shape" fill="url(#linearGradient-3)"></path>
+                    </g>
+                    <ellipse id="Combined-Shape" fill="url(#linearGradient-4)" cx="100.519339" cy="100.436681" rx="23.6001926" ry="23.580786"></ellipse>
+                </g>
+            </g>
+        </g>
+    </g>
+</svg>

+ 5 - 4
src/components/Breadcrumb.vue

@@ -22,13 +22,14 @@ export default {
   },
   methods: {
     getBreadcrumb() {
-      this.breadList = this.$route.matched
+
+      this.breadList = []
+      this.breadList.push({ name: 'index', path: '/dashboard/', meta: { title: '首页' } })
+
       this.name = this.$route.name
       this.$route.matched.forEach((item) => {
         // item.meta.name === 'dashboard' ? item.path = '/dashboard' : this.$route.path === item.path
-        if (item.name === undefined) {
-          item.meta.title = '首页'
-        }
+          this.breadList.push(item)
       })
     }
   },

+ 83 - 0
src/components/LayoutHeader.vue

@@ -0,0 +1,83 @@
+<template>
+    <a-layout-header style="padding: 0px;">
+        <div class="header">
+            <a-icon class="trigger" :type="collapsed ? 'menu-unfold' : 'menu-fold'" @click.native="toggle"/>
+            <div class="user-wrapper">
+                <span class="action">
+                    <a-icon type="question-circle-o"></a-icon>
+                </span>
+                <span class="action">
+                    <a-badge count="12">
+                        <a-icon class="icon" type="bell"></a-icon>
+                    </a-badge>
+                </span>
+                <a-dropdown>
+                    <span class="action ant-dropdown-link user-dropdown-menu">
+                      <a-avatar class="avatar" size="small" src="https://gw.alipayobjects.com/zos/rmsportal/BiazfanxmamNRoxxVxka.png"/>
+                      <span>{{ nickname() }}</span>
+                    </span>
+                    <a-menu slot="overlay" class="user-dropdown-menu-wrapper">
+                        <a-menu-item key="0">
+                            <a-icon type="user"/>
+                            <span>个人中心</span>
+                        </a-menu-item>
+                        <a-menu-item key="1">
+                            <a-icon type="setting"/>
+                            <span>账户设置</span>
+                        </a-menu-item>
+                        <a-menu-item key="2" disabled>
+                            <a-icon type="setting"/>
+                            <span>测试</span>
+                        </a-menu-item>
+                        <a-menu-divider/>
+                        <a-menu-item key="3">
+                            <a-icon type="logout"/>
+                            <span @click="handleLogout">退出登录</span>
+                        </a-menu-item>
+                    </a-menu>
+                </a-dropdown>
+            </div>
+        </div>
+    </a-layout-header>
+</template>
+
+<script>
+  import { mapActions, mapGetters } from 'vuex'
+
+  export default {
+    name: "LayoutHeader",
+    props: {
+      collapsed: {
+        type: Boolean,
+        required: false,
+        default: false
+      },
+    },
+    data() {
+      return {
+
+      }
+    },
+    created() {
+
+    },
+    methods: {
+      ...mapActions(["Logout"]),
+      ...mapGetters(["nickname"]),
+      handleLogout() {
+        this.Logout({}).then(() => {
+          window.location.reload()
+        }).catch(err => {
+          this.$message.error(err.message)
+        })
+      },
+      toggle() {
+        this.$emit('toggle')
+      }
+    }
+  }
+</script>
+
+<style scoped>
+
+</style>

+ 0 - 93
src/components/NavMenu.vue

@@ -1,93 +0,0 @@
-<template>
-    <a-menu
-            theme="dark"
-            mode="inline"
-            :defaultSelectedKeys="['1']">
-
-        <template v-for="menu in menus">
-            <a-menu-item :key="menu.id" :name="menu.id" v-if="!menu.children && $router.matcher.match({ name: menu.permission }).matched.length">
-                <router-link :to="{ name: menu.name, params: { pageNo: '1' } }">
-                    <a-icon v-if="menu.meta.icon" :type="menu.meta.icon"></a-icon>
-                    <span>{{ menu.meta.title }}</span>
-                </router-link>
-            </a-menu-item>
-            <a-sub-menu :key="menu.id" :name="menu.id" v-else>
-                <span slot="title"><a-icon :type="menu.meta.icon" v-if="menu.meta.icon" /><span>{{ menu.meta.title }}</span></span>
-                <template v-for="(submenu, index) in menu.children">
-                    <a-menu-item :key="submenu.id" :name="submenu.id">
-                        <router-link :to="{ name: submenu.name, params: { pageNo: '1' } }">
-                            <a-icon v-if="submenu.meta.icon" :type="submenu.meta.icon"></a-icon>
-                            <span>{{ submenu.meta.title }}</span>
-                        </router-link>
-                    </a-menu-item>
-                </template>
-            </a-sub-menu>
-
-        </template>
-        <!--
-        <a-sub-menu key="1">
-            <span slot="title"><a-icon type="dashboard" /><span>dashboard</span></span>
-            <a-menu-item key="11">分析页</a-menu-item>
-            <a-menu-item key="12">监控页</a-menu-item>
-            <a-menu-item key="13">工作台</a-menu-item>
-        </a-sub-menu>
-        <a-sub-menu key="2">
-            <span slot="title"><a-icon type="form" /><span>表单页</span></span>
-            <a-menu-item key="21">基础表单</a-menu-item>
-            <a-menu-item key="22">分步表单</a-menu-item>
-            <a-menu-item key="23">高级表单</a-menu-item>
-        </a-sub-menu>
-        <a-sub-menu key="3">
-            <span slot="title"><a-icon type="table" /><span>列表页</span></span>
-            <a-menu-item key="31">查询表单</a-menu-item>
-            <a-menu-item key="32">表单列表</a-menu-item>
-            <a-menu-item key="33">卡片列表</a-menu-item>
-            <a-sub-menu key="34">
-                <span slot="title"><span>搜索列表</span></span>
-                <a-menu-item key="341">搜索列表(文章)</a-menu-item>
-                <a-menu-item key="342">表单列表(项目)</a-menu-item>
-                <a-menu-item key="343">卡片列表(应用)</a-menu-item>
-            </a-sub-menu>
-        </a-sub-menu>
-        <a-sub-menu key="4">
-            <span slot="title"><a-icon type="profile" /><span>详细页</span></span>
-            <a-menu-item key="41">基础详情页</a-menu-item>
-            <a-menu-item key="42">高级详情页</a-menu-item>
-        </a-sub-menu>
-        <a-sub-menu key="5">
-            <span slot="title"><a-icon type="check-circle-o" /><span>结果页</span></span>
-            <a-menu-item key="51">成功</a-menu-item>
-            <a-menu-item key="52">失败</a-menu-item>
-        </a-sub-menu>
-        <a-sub-menu key="6">
-            <span slot="title"><a-icon type="warning" /><span>异常页</span></span>
-            <a-menu-item key="61">成功</a-menu-item>
-            <a-menu-item key="62">失败</a-menu-item>
-        </a-sub-menu>
-        -->
-    </a-menu>
-</template>
-
-<script>
-import SubMenu from './SubMenu'
-import { asyncRouterMap } from '../router/'
-
-export default {
-  name: "Navmenu",
-  components: {
-      "s-submenu": SubMenu
-  },
-  data() {
-    return {
-      menus: []
-    }
-  },
-  created() {
-    this.menus = asyncRouterMap
-  }
-}
-</script>
-
-<style scoped>
-
-</style>

+ 0 - 32
src/components/SubMenu.vue

@@ -1,32 +0,0 @@
-<template>
-    <a-menu-item :key="menu.id" :name="menu.id" v-if="!menu.children && router.matcher.match({ name: menu.permission }).matched.length">
-        <router-link :to="{ name: menu.permission, params: { pageNo: '1' } }">
-            <a-icon v-if="menu.icon" :type="menu.icon"></a-icon>
-            <span>{{ menu.name }}</span>
-        </router-link>
-    </a-menu-item>
-    <a-submenu :key="menu.id" :name="menu.id" v-else>
-        <span slot="title"><a-icon :type="menu.icon" v-if="menu.icon" /><span>{{ menu.name }}</span></span>
-        <template v-for="(submenu, index) in menu.children">
-            <s-submenu :key="submenu.id" :menu="submenu"></s-submenu>
-        </template>
-    </a-submenu>
-</template>
-
-<script>
-import SubMenu from './SubMenu'
-
-export default {
-    name: "SubMenu",
-  components: {
-      "s-submenu": SubMenu
-  },
-  props: {
-    menu: {},
-    collapsed: {
-      type: Boolean,
-      default: false
-    }
-  }
-}
-</script>

+ 36 - 0
src/components/menu/NavMenu.vue

@@ -0,0 +1,36 @@
+<template>
+    <a-menu
+            theme="dark"
+            mode="inline"
+            :defaultSelectedKeys="['1']">
+
+        <template v-for="menu in menus">
+            <s-submenu :menu="menu" :key="menu.id"></s-submenu>
+        </template>
+
+    </a-menu>
+</template>
+
+<script>
+import SubMenu from './SubMenu'
+import { asyncRouterMap } from '../../router/index'
+
+export default {
+  name: "NavMenu",
+  components: {
+      "s-submenu": SubMenu
+  },
+  data() {
+    return {
+      menus: []
+    }
+  },
+  created() {
+    this.menus = asyncRouterMap
+  }
+}
+</script>
+
+<style scoped>
+
+</style>

+ 53 - 0
src/components/menu/SiderMenu.vue

@@ -0,0 +1,53 @@
+<template>
+    <a-layout-sider :class="['sider', isMobile ? null : 'shadow' ]" width="256px" :collapsible="collapsible" v-model="collapsed" :trigger="null">
+        <div class="logo">
+            <router-link :to="{name:'dashboard'}">
+                <img src="~@/assets/logo.svg" alt="logo">
+                <h1>Ant Design Pro</h1>
+            </router-link>
+        </div>
+        <s-menu :collapsed="collapsed" :menu="menus" @select="onSelect"></s-menu>
+    </a-layout-sider>
+</template>
+
+<script>
+    import ALayoutSider from "ant-design-vue/es/layout/Sider"
+    import SMenu from './index'
+    export default {
+        name: "SiderMenu",
+        components: {ALayoutSider, SMenu },
+        props: {
+            collapsible: {
+                type: Boolean,
+                required: false,
+                default: false
+            },
+            collapsed: {
+                type: Boolean,
+                required: false,
+                default: false
+            },
+            menus: {
+                type: Array,
+                required: true
+            }
+        },
+        created() {
+
+        },
+        computed: {
+            isMobile () {
+                return this.$store.state.app.device !== 'desktop'
+            }
+        },
+        methods: {
+            onSelect(obj) {
+                this.$emit('menuSelect', obj)
+            }
+        }
+    }
+</script>
+
+<style scoped>
+
+</style>

+ 32 - 0
src/components/menu/SubMenu.vue

@@ -0,0 +1,32 @@
+<template>
+    <a-menu-item :key="menu.id" v-if="!menu.children && $router.matcher.match({ name: menu.permission }).matched.length">
+        <router-link :to="{ name: menu.name, params: { pageNo: '1' } }">
+            <a-icon v-if="menu.meta.icon" :type="menu.meta.icon"></a-icon>
+            <span>{{ menu.meta.title }}</span>
+        </router-link>
+    </a-menu-item>
+    <a-sub-menu :key="menu.id" v-else>
+        <span slot="title"><a-icon :type="menu.meta.icon" v-if="menu.meta.icon" /><span>{{ menu.meta.title }}</span></span>
+        <template v-for="submenu in menu.children">
+            <s-submenu :key="submenu.id" :menu="submenu"></s-submenu>
+        </template>
+    </a-sub-menu>
+</template>
+
+<script>
+import SubMenu from './SubMenu'
+
+export default {
+    name: "SubMenu",
+  components: {
+      "s-submenu": SubMenu
+  },
+  props: {
+    menu: {},
+    collapsed: {
+      type: Boolean,
+      default: false
+    }
+  }
+}
+</script>

+ 144 - 0
src/components/menu/index.js

@@ -0,0 +1,144 @@
+import Menu from 'ant-design-vue/es/menu'
+import Icon from 'ant-design-vue/es/icon'
+
+const { Item, SubMenu } = Menu
+
+export default {
+    name: 'SMenu',
+    props: {
+        menu: {
+            type: Array,
+            required: true
+        },
+        theme: {
+            type: String,
+            required: false,
+            default: 'dark'
+        },
+        mode: {
+            type: String,
+            required: false,
+            default: 'inline'
+        },
+        collapsed: {
+            type: Boolean,
+            required: false,
+            default: false
+        }
+    },
+    data () {
+        return {
+            rootSubmenuKeys: [],
+            openKeys: [],
+            selectedKeys: [],
+            cachedOpenKeys: []
+        }
+    },
+    created () {
+        this.updateMenu()
+    },
+    watch: {
+        collapsed (val) {
+            if (val) {
+                this.cachedOpenKeys = this.openKeys
+                this.openKeys = []
+            } else {
+                this.openKeys = this.cachedOpenKeys
+            }
+        },
+        '$route': function () {
+            this.updateMenu()
+        }
+    },
+    methods: {
+        renderIcon: function (h, icon) {
+            return icon === 'none' || icon === undefined ? null
+                : h( Icon, { props: { type: icon !== undefined ? icon : '' } })
+        },
+        renderMenuItem: function (h, menu, pIndex, index) {
+            return h( Item, { key: menu.path ? menu.path : 'item_' + pIndex + '_' + index },
+                [
+                    h(
+                        'router-link',
+                        { attrs: { to: { name: menu.name }  }},
+                        [
+                            this.renderIcon(h, menu.meta.icon),
+                            h('span', [menu.meta.title])
+                        ]
+                    )
+                ]
+            )
+        },
+        renderSubMenu: function (h, menu, pIndex, index) {
+            var this2_ = this
+            var subItem = [h('span',
+                {slot: 'title'},
+                [
+                    this.renderIcon(h, menu.meta.icon),
+                    h('span', [menu.meta.title])
+                ]
+            )]
+            var itemArr = []
+            var pIndex_ = pIndex + '_' + index
+            menu.children.forEach(function (item, i) {
+                itemArr.push(this2_.renderItem(h, item, pIndex_, i))
+            })
+            return h(
+                SubMenu,
+                {key: menu.path ? menu.path : 'submenu_' + pIndex + '_' + index},
+                subItem.concat(itemArr)
+            )
+        },
+        renderItem: function (h, menu, pIndex, index) {
+            if (!menu.invisible) {
+                return menu.children ? this.renderSubMenu(h, menu, pIndex, index) : this.renderMenuItem(h, menu, pIndex, index)
+            }
+        },
+        renderMenu: function (h, menuTree) {
+            var this2_ = this
+            var menuArr = []
+            menuTree.forEach(function (menu, i) {
+                menuArr.push(this2_.renderItem(h, menu, '0', i))
+            })
+            return menuArr
+        },
+        onOpenChange (openKeys) {
+            const latestOpenKey = openKeys.find(key => this.openKeys.indexOf(key) === -1)
+            if (this.rootSubmenuKeys.indexOf(latestOpenKey) === -1) {
+                this.openKeys = openKeys
+            } else {
+                this.openKeys = latestOpenKey ? [latestOpenKey] : []
+            }
+        },
+        updateMenu () {
+            let routes = this.$route.matched.concat()
+            this.selectedKeys = [routes.pop().path]
+            let openKeys = []
+            routes.forEach((item) => {
+                openKeys.push(item.path)
+            })
+            this.collapsed ? this.cachedOpenKeys = openKeys : this.openKeys = openKeys
+        }
+    },
+    render (h) {
+        return h(
+            Menu,
+            {
+                props: {
+                    theme: this.$props.theme,
+                    mode: this.$props.mode,
+                    inlineCollapsed: false,
+                    openKeys: this.openKeys,
+                    selectedKeys: this.selectedKeys
+                },
+                on: {
+                    openChange: this.onOpenChange,
+                    select: (obj) => {
+                        this.selectedKeys = obj.selectedKeys
+                        this.$emit('select', obj)
+                    }
+                }
+            }, this.renderMenu(h, this.menu)
+        )
+    }
+}

+ 2 - 5
src/permission.js

@@ -24,18 +24,15 @@ router.beforeEach((to, from, next) => {
       if (store.getters.roles.length === 0) {
 
         store.dispatch('GetInfo').then(res => {
-          const roles = ['editor', 'develop']
+          const roles = res.result && res.result.role
           store.dispatch('GenerateRoutes', { roles }).then(() => { // 根据roles权限生成可访问的路由表
-
-            console.log( 'dispatch::GenerateRoutes succeeded.' )
-
             router.addRoutes(store.getters.addRouters) // 动态添加可访问路由表
             next({ ...to, replace: true }) // hack方法 确保addRoutes已完成 ,set the replace: true so the navigation will not leave a history record
           })
         }).catch((err) => {
           store.dispatch('FedLogout').then(() => {
-            console.log(err)
             Vue.$message.error('This is a message of error');
+            Vue.$message.error(err.message)
           })
         })
 

+ 36 - 24
src/router/index.js

@@ -49,19 +49,19 @@ export const asyncRouterMap = [
     meta: { title: 'dashboard', icon: 'dashboard' },
     children: [
       {
-        path: 'analysis',
+        path: '/dashboard/analysis',
         name: 'Analysis',
         component: () => import('../views/dashboard/Analysis'),
         meta: { title: '分析页', hideHeader: true }
       },
       {
-        path: 'monitor',
+        path: '/dashboard/monitor',
         name: 'Monitor',
         component: () => import('../views/dashboard/Monitor'),
         meta: { title: '监控页', hideHeader: true }
       },
       {
-        path: 'workplace',
+        path: '/dashboard/workplace',
         name: 'Workplace',
         component: () => import('../views/dashboard/Workplace'),
         meta: { title: '工作台', hideHeader: true }
@@ -72,22 +72,23 @@ export const asyncRouterMap = [
     path: '/form',
     component: Layout,
     name: 'form',
+    redirect: '/form/base-form',
     meta: { title: '表单页', icon: 'form' },
     children: [
       {
-        path: 'base-form',
+        path: '/form/base-form',
         name: 'BaseForm',
         component: () => import('../views/form/BasicForm'),
         meta: { title: '基础表单' }
       },
       {
-        path: 'step-form',
+        path: '/form/step-form',
         name: 'StepForm',
         component: () => import('../views/form/BasicForm'),
         meta: { title: '分步表单' }
       },
       {
-        path: 'advanced-form',
+        path: '/form/advanced-form',
         name: 'AdvanceForm',
         component: () => import('../views/form/BasicForm'),
         meta: { title: '高级表单' }
@@ -98,42 +99,50 @@ export const asyncRouterMap = [
     path: '/list',
     component: Layout,
     name: 'list',
+    redirect: '/list/query',
     meta: { title: '列表页', icon: 'table' },
     children: [
       {
-        path: 'table-list',
-        name: 'TableList',
+        path: '/list/query',
+        name: 'QueryList',
         component: () => import('../views/list/TableList'),
         meta: { title: '查询表格' }
       },
       {
-        path: 'basic-list',
+        path: '/list/basic',
         name: 'BasicList',
         component: () => import('../views/list/TableList'),
         meta: { title: '标准列表' }
       },
       {
-        path: 'card-list',
+        path: '/list/card',
         name: 'CardList',
         component: () => import('../views/list/TableList'),
         meta: { title: '卡片列表' }
       },
       {
-        path: 'search',
+        path: '/list/search',
         name: 'SearchList',
+        redirect: '/list/search/articles',
         meta: { title: '搜索列表' },
         children: [
           {
-            path: 'articles',
-            name: 'Articles',
+            path: '/list/search/articles',
+            name: 'SearchArticles',
             component: () => import('../views/list/TableList'),
             meta: { title: '搜索列表(文章)' }
           },
           {
-            path: 'articles',
-            name: 'Articles',
-            component: () => import('../views/list/TableList'),
-            meta: { title: '搜索列表(文章)' }
+              path: '/list/search/projects',
+              name: 'SearchProjects',
+              component: () => import('../views/list/TableList'),
+              meta: { title: '搜索列表(项目)' }
+          },
+          {
+              path: '/list/search/applications',
+              name: 'SearchApplications',
+              component: () => import('../views/list/TableList'),
+              meta: { title: '搜索列表(应用)' }
           },
         ]
       },
@@ -143,16 +152,17 @@ export const asyncRouterMap = [
     path: '/profile',
     component: Layout,
     name: 'profile',
+    redirect: '/profile/basic',
     meta: { title: '详情页', icon: 'profile' },
     children: [
       {
-        path: 'basic',
+        path: '/profile/basic',
         name: 'ProfileBasic',
         component: () => import('../views/list/TableList'),
         meta: { title: '基础详情页' }
       },
       {
-        path: 'advanced',
+        path: '/profile/advanced',
         name: 'ProfileAdvanced',
         component: () => import('../views/list/TableList'),
         meta: { title: '高级详情页' }
@@ -163,16 +173,17 @@ export const asyncRouterMap = [
     path: '/result',
     component: Layout,
     name: 'result',
+    redirect: '/result/success',
     meta: { title: '结果页', icon: 'check-circle-o' },
     children: [
       {
-        path: 'success',
+        path: '/result/success',
         name: 'ResultSuccess',
         component: () => import('../views/result/Success'),
         meta: { title: '成功' }
       },
       {
-        path: 'fail',
+        path: '/result/fail',
         name: 'ResultFail',
         // route level code-splitting
         // this generates a separate chunk (about.[hash].js) for this route
@@ -186,16 +197,17 @@ export const asyncRouterMap = [
     path: '/exception',
     component: Layout,
     name: 'exception',
+    redirect: '/exception/403',
     meta: { title: '异常页', icon: 'warning' },
     children: [
       {
-        path: '403',
+        path: '/exception/403',
         name: 'Exception403',
         component: () => import('../views/result/Success'),
         meta: { title: '403' }
       },
       {
-        path: '404',
+        path: '/exception/404',
         name: 'Exception404',
         // route level code-splitting
         // this generates a separate chunk (about.[hash].js) for this route
@@ -204,7 +216,7 @@ export const asyncRouterMap = [
         meta: { title: '404' }
       },
       {
-        path: '500',
+        path: '/exception/500',
         name: 'Exception500',
         // route level code-splitting
         // this generates a separate chunk (about.[hash].js) for this route

+ 2 - 0
src/store/getters.js

@@ -1,6 +1,8 @@
 const getters = {
   device: state => state.app.device,
   token: state => state.user.token,
+  avatar: state => state.user.avatar,
+  nickname: state => state.user.name,
   roles: state => state.user.roles,
   addRouters: state => state.permission.addRouters
 }

+ 16 - 4
src/store/modules/permission.js

@@ -1,5 +1,12 @@
 import { asyncRouterMap, constantRouterMap } from "@/router"
 
+/**
+ * 过滤账户是否拥有某一个权限,并将菜单从加载列表移除
+ *
+ * @param permission
+ * @param route
+ * @returns {boolean}
+ */
 function hasPermission(permission, route) {
   if (route.meta && route.meta.permission) {
     let flag = -1
@@ -10,8 +17,17 @@ function hasPermission(permission, route) {
       }
     }
   }
+  return true
 }
 
+/**
+ * 单账户多角色时,使用该方法可过滤角色不存在的菜单
+ *
+ * @param roles
+ * @param route
+ * @returns {*}
+ */
+// eslint-disable-next-line
 function hasRole(roles, route) {
   if (route.meta && route.meta.roles) {
     return route.meta.roles.indexOf(roles.id)
@@ -21,9 +37,6 @@ function hasRole(roles, route) {
 }
 
 function filterAsyncRouter(asyncRouterMap, roles) {
-  console.log(asyncRouterMap, roles)
-  return asyncRouterMap
-/*
   const accessedRouters = asyncRouterMap.filter(route => {
     if (hasPermission(roles.permissionList, route)) {
       if (route.children && route.children.length) {
@@ -34,7 +47,6 @@ function filterAsyncRouter(asyncRouterMap, roles) {
     return false
   })
   return accessedRouters
-  */
 }
 
 const permission = {

+ 7 - 10
src/store/modules/user.js

@@ -1,8 +1,9 @@
-import { login, getInfo, logout } from "@/api/login";
+import { login, getInfo, logout } from "@/api/login"
+import { setToken, getToken, removeToken } from '@/utils/auth'
 
 const user = {
   state: {
-    token: '',
+    token: getToken(),
     name: '',
     avatar: '',
     roles: []
@@ -26,13 +27,9 @@ const user = {
   actions: {
     // 登录
     Login({ commit }, userInfo) {
-      const username = userInfo.username.trim()
       return new Promise((resolve, reject) => {
-        login(username, userInfo.password).then(response => {
+        login(userInfo).then(response => {
           const result = response.result
-
-          console.log('login:', result)
-
           setToken(result.token)
           commit('SET_TOKEN', result.token)
           resolve()
@@ -43,7 +40,7 @@ const user = {
     },
 
     // 获取用户信息
-    GetInfo({ commit, state }) {
+    GetInfo({ commit }) {
       return new Promise((resolve, reject) => {
         getInfo().then(response => {
           const result = response.result
@@ -79,7 +76,7 @@ const user = {
         logout(state.token).then(() => {
           commit('SET_TOKEN', '')
           commit('SET_ROLES', [])
-          // removeToken()
+          removeToken()
           resolve()
         }).catch(error => {
           reject(error)
@@ -91,7 +88,7 @@ const user = {
     FedLogout({ commit }) {
       return new Promise(resolve => {
         commit('SET_TOKEN', '')
-        // removeToken()
+        removeToken()
         resolve()
       })
     }

File diff suppressed because it is too large
+ 0 - 8
src/views/Layout.vue


+ 346 - 2
src/views/Login.vue

@@ -1,5 +1,349 @@
 <template>
-  <div class="login">
-    <h1>This is an login page</h1>
+  <div id="auth">
+    <div class="container">
+      <div class="top">
+        <div class="header">
+          <a href="/">
+            <img src="~@/assets/logo.svg" class="logo" alt="logo">
+            <span class="title">Ant Design</span>
+          </a>
+        </div>
+        <div class="desc">
+          Ant Design 是西湖区最具影响力的 Web 设计规范
+        </div>
+      </div>
+      <div class="main">
+        <a-form ref="formLogin" :autoFormCreate="(form)=>{this.form = form}" id="formLogin">
+
+          <a-tabs :activeKey="customActiveKey" :tabBarStyle="{ textAlign: 'center', borderBottom: 'unset' }" @change="handleTabClick">
+            <a-tab-pane key="tab1" tab="账号密码登陆">
+
+              <a-form-item
+                      fieldDecoratorId="username"
+                      :fieldDecoratorOptions="{rules: [{ required: true, message: '请输入帐户名或邮箱地址' }, { validator: this.handleUsernameOrEmail }], validateTrigger: 'blur'}"
+              >
+                <a-input size="large" type="text" v-model="formLogin.username" placeholder="帐户名或邮箱地址">
+                  <a-icon slot="prefix" type='user' :style="{ color: 'rgba(0,0,0,.25)' }" />
+                </a-input>
+              </a-form-item>
+
+              <a-form-item
+                      fieldDecoratorId="password"
+                      :fieldDecoratorOptions="{rules: [{ required: true, message: '请输入密码' }], validateTrigger: 'blur'}">
+                <a-input size="large" type="password" v-model="formLogin.password" placeholder="密码">
+                  <a-icon slot="prefix" type='lock' :style="{ color: 'rgba(0,0,0,.25)' }" />
+                </a-input>
+              </a-form-item>
+            </a-tab-pane>
+            <a-tab-pane key="tab2" tab="手机号登陆">
+              <a-form-item
+                      fieldDecoratorId="mobile"
+                      :fieldDecoratorOptions="{rules: [{ required: true, pattern: /^1[34578]\d{9}$/, message: '请输入正确的手机号' }], validateTrigger: 'blur'}">
+                <a-input size="large" type="text" v-model="formLogin.mobile" placeholder="手机号">
+                  <a-icon slot="prefix" type='mobile' :style="{ color: 'rgba(0,0,0,.25)' }" />
+                </a-input>
+              </a-form-item>
+
+              <a-row :gutter="16">
+                <a-col class="gutter-row" :span="16">
+                  <a-form-item
+                          fieldDecoratorId="captcha"
+                          :fieldDecoratorOptions="{rules: [{ required: true, message: '请输入验证码' }], validateTrigger: 'blur'}">
+                    <a-input size="large" type="text" v-model="formLogin.captcha" placeholder="验证码">
+                      <a-icon slot="prefix" type='mail' :style="{ color: 'rgba(0,0,0,.25)' }" />
+                    </a-input>
+                  </a-form-item>
+                </a-col>
+                <a-col class="gutter-row" :span="8">
+                    <span class="ivu-input-prefix">
+                      <a-button class="getCaptcha" :disabled="state.smsSendBtn"
+                                @click.stop.prevent="getCaptcha" v-text="!state.smsSendBtn&&'获取验证码'||(state.time+' s')"></a-button>
+                    </span>
+                </a-col>
+              </a-row>
+
+            </a-tab-pane>
+          </a-tabs>
+
+          <a-form-item>
+            <a-checkbox v-model="formLogin.rememberMe">自动登陆</a-checkbox>
+            <router-link :to="{ name: 'recover', params: { user: 'aaa'} }" class="forge-password" style="float: right;">忘记密码</router-link>
+          </a-form-item>
+
+          <a-form-item style="margin-top:24px">
+            <a-button size="large" type="primary"
+                      htmlType="submit" class="login-button" :loading="loginBtn"
+                      @click.stop.prevent="handleSubmit" v-bind:disabled="loginBtn" >确定</a-button>
+          </a-form-item>
+
+        </a-form>
+      </div>
+      <div class="footer">
+        <div class="links">
+          <a href="_self">帮助</a>
+          <a href="_self">隐私</a>
+          <a href="_self">条款</a>
+        </div>
+        <div class="copyright">
+          Copyright &copy; 2018 白鹭学园技术组出品
+        </div>
+      </div>
+    </div>
   </div>
 </template>
+
+<script>
+  import md5 from "md5";
+  import api from '../api/'
+  import { mapActions } from "vuex";
+
+  export default {
+      data() {
+          return {
+              customActiveKey: "tab1",
+              loginBtn: false,
+              // login type: 0 email, 1 username, 2 telephone
+              loginType: 0,
+              form: null,
+              state: {
+                  time: 60,
+                  smsSendBtn: false,
+              },
+              formLogin: {
+                  username: "",
+                  password: "",
+                  captcha: "",
+                  mobile: "",
+                  rememberMe: true
+              },
+          }
+      },
+      methods: {
+          ...mapActions(["Login"]),
+          // handler
+          handleUsernameOrEmail(rule, value, callback) {
+              const regex = /^([a-zA-Z0-9_-])+@([a-zA-Z0-9_-])+((\.[a-zA-Z0-9_-]{2,3}){1,2})$/;
+              if (regex.test(value)) {
+                  this.loginType = 0
+              } else {
+                  this.loginType = 1
+              }
+              callback()
+          },
+          handleTabClick(key) {
+              this.customActiveKey = key
+              this.form.resetFields()
+          },
+          handleSubmit() {
+              let flag = false
+
+              if (this.customActiveKey === 'tab1') {
+                  this.form.validateFields(['username', 'password'], { force: true }, (err) => {
+                      if (!err) {
+                          flag = true
+                      }
+                  })
+              } else {
+                  this.form.validateFields(['mobile', 'captcha'], { force: true }, (err) => {
+                      if (!err) {
+                          flag = true
+                          this.loginType = 2 // 登录类型修改为手机登录
+                      }
+                  })
+              }
+
+              if (!flag) return
+
+              this.loginBtn = true
+
+              let loginParams = {
+                  password: md5(this.formLogin.password),
+                  remember_me: this.formLogin.rememberMe
+              };
+
+              switch (this.loginType) {
+                  case 0:
+                      loginParams.email = this.formLogin.username
+                      break;
+                  case 1:
+                      loginParams.username = this.formLogin.username
+                      break;
+                  case 2:
+                  default:
+                      loginParams.mobile = this.formLogin.mobile
+                      loginParams.captcha = this.formLogin.captcha
+                      break;
+              }
+
+              this.Login(loginParams).then(() => {
+                  this.loginBtn = false
+                  this.$router.push({ name: "dashboard" })
+              }).catch((err) => {
+                  this.requestFailed(err);
+              })
+
+          },
+          getCaptcha(e) {
+              e.preventDefault()
+              let that = this
+
+              this.form.validateFields(['mobile'], { force: true },
+                  (err) => {
+                      if (!err) {
+                          this.state.smsSendBtn = true;
+
+                          let interval = window.setInterval(() => {
+                              if (that.state.time-- <= 0) {
+                                  that.state.time = 60;
+                                  that.state.smsSendBtn = false;
+                                  window.clearInterval(interval);
+                              }
+                          }, 1000);
+
+                          const hide = this.$message.loading('验证码发送中..', 0);
+                          this.$http.post(api.SendSms, { mobile: that.formLogin.mobile })
+                              .then(res => {
+                                  setTimeout(hide, 2500);
+                                  this.$notification['success']({
+                                      message: '提示',
+                                      description: '验证码获取成功,您的验证码为:' + res.result.captcha,
+                                  })
+                              })
+                              .catch(err => {
+                                  setTimeout(hide, 1);
+                                  clearInterval(interval);
+                                  that.state.time = 60;
+                                  that.state.smsSendBtn = false;
+                                  this.requestFailed(err);
+                              });
+                      }
+                  }
+              );
+          },
+          requestFailed(err) {
+              this.$notification['error']({
+                  message: '错误',
+                  description: ((err.response || {}).data || {}).message || "请求出现错误,请稍后再试",
+                  duration: 4,
+              });
+              this.loginBtn = false;
+          },
+      }
+  }
+</script>
+
+<style lang="scss" scoped>
+
+  #auth {
+    height: 100%;
+
+    .container {
+      width: 100%;
+      min-height: 100%;
+      background: #f0f2f5 url(~@/assets/background.svg) no-repeat 50%;
+      background-size: 100%;
+      padding: 110px 0 144px;
+      position: relative;
+
+      a {
+        text-decoration: none;
+      }
+
+      .top {
+        text-align: center;
+
+        .header {
+          height: 44px;
+          line-height: 44px;
+
+          .badge {
+            position: absolute;
+            display: inline-block;
+            line-height: 1;
+            vertical-align: middle;
+            margin-left: -12px;
+            margin-top: -10px;
+            opacity: 0.8;
+          }
+
+          .logo {
+            height: 44px;
+            vertical-align: top;
+            margin-right: 16px;
+            border-style: none;
+          }
+
+          .title {
+            font-size: 33px;
+            color: rgba(0,0,0,.85);
+            font-family: "Myriad Pro","Helvetica Neue",Arial,Helvetica,sans-serif;
+            font-weight: 600;
+            position: relative;
+            top: 2px;
+          }
+        }
+        .desc {
+          font-size: 14px;
+          color: rgba(0, 0, 0, 0.45);
+          margin-top: 12px;
+          margin-bottom: 40px;
+        }
+      }
+
+      .main {
+        width: 368px;
+        margin: 0 auto;
+
+        label {
+          font-size: 14px;
+        }
+
+        .ivu-input-prefix {
+          left: 12px;
+          font-size: 14px;
+          color: rgba(0, 0, 0, 0.25);
+        }
+        .getCaptcha {
+          display: block;
+          width: 100%;
+          height: 40px;
+        }
+
+        .forge-password {
+          font-size: 14px;
+        }
+        button.login-button {
+          padding: 0 15px;
+          font-size: 16px;
+          height: 40px;
+          width: 100%;
+        }
+      }
+
+      .footer {
+        position: absolute;
+        width: 100%;
+        bottom: 0;
+        padding: 0 16px;
+        margin: 48px 0 24px;
+        text-align: center;
+
+        .links {
+          margin-bottom: 8px;
+          font-size: 14px;
+          a {
+            color: rgba(0, 0, 0, 0.45);
+            transition: all 0.3s;
+            &:not(:last-child) {
+              margin-right: 40px;
+            }
+          }
+        }
+        .copyright {
+          color: rgba(0, 0, 0, 0.45);
+          font-size: 14px;
+        }
+      }
+    }
+  }
+</style>

+ 529 - 19
yarn.lock

@@ -2,6 +2,109 @@
 # yarn lockfile v1
 
 
+"@antv/adjust@~0.0.6":
+  version "0.0.6"
+  resolved "https://registry.yarnpkg.com/@antv/adjust/-/adjust-0.0.6.tgz#16db3000dd315607acda8f6968caf7b58c36f3a8"
+  dependencies:
+    "@antv/util" "~1.0.11"
+
+"@antv/attr@~0.0.6":
+  version "0.0.6"
+  resolved "https://registry.yarnpkg.com/@antv/attr/-/attr-0.0.6.tgz#5b3886512cd290c1bd179e9613f3197243dc0557"
+  dependencies:
+    "@antv/util" "~1.0.11"
+
+"@antv/data-set@^0.8.9":
+  version "0.8.9"
+  resolved "https://registry.yarnpkg.com/@antv/data-set/-/data-set-0.8.9.tgz#019b3ec73a1309d57dfb379200b8ae02486fa613"
+  dependencies:
+    "@antv/hierarchy" "~0.1.0-beta.2"
+    d3-array "~1.2.0"
+    d3-composite-projections "~1.2.0"
+    d3-dsv "~1.0.5"
+    d3-geo "~1.6.4"
+    d3-geo-projection "~2.1.2"
+    d3-hexjson "~1.0.1"
+    d3-hierarchy "~1.1.5"
+    d3-sankey "~0.7.1"
+    d3-voronoi "~1.1.2"
+    dagre "~0.8.2"
+    lodash "~4.17.4"
+    point-at-length "~1.0.2"
+    regression "~2.0.0"
+    simple-statistics "~4.1.0"
+    topojson-client "~3.0.0"
+    wolfy87-eventemitter "~5.1.0"
+
+"@antv/g2-brush@^0.0.2":
+  version "0.0.2"
+  resolved "https://registry.yarnpkg.com/@antv/g2-brush/-/g2-brush-0.0.2.tgz#0b65f3ebbf82690202913d0b6759ab2900faa841"
+
+"@antv/g2-plugin-slider@^2.0.2":
+  version "2.0.4"
+  resolved "https://registry.yarnpkg.com/@antv/g2-plugin-slider/-/g2-plugin-slider-2.0.4.tgz#3c65f44a38fed3b8c58ca4e1142f249f27747be6"
+
+"@antv/g2@^3.2.0":
+  version "3.2.7"
+  resolved "https://registry.yarnpkg.com/@antv/g2/-/g2-3.2.7.tgz#ea3c7c008bbf016af28f8013687b541f291a012d"
+  dependencies:
+    "@antv/adjust" "~0.0.6"
+    "@antv/attr" "~0.0.6"
+    "@antv/g" "~3.1.1"
+    "@antv/interaction" "~0.1.5"
+    "@antv/scale" "~0.0.5"
+    "@antv/util" "~1.0.12"
+    venn.js "~0.2.20"
+    wolfy87-eventemitter "~5.1.0"
+
+"@antv/g@3.1.0-beta.6":
+  version "3.1.0-beta.6"
+  resolved "https://registry.yarnpkg.com/@antv/g/-/g-3.1.0-beta.6.tgz#d9e2f53e288b6fb4dcb2787bba8d6d5527664484"
+  dependencies:
+    "@antv/gl-matrix" "~2.7.1"
+    "@antv/util" "~1.0.11"
+    d3-ease "~1.0.3"
+    d3-interpolate "~1.1.5"
+    d3-timer "~1.0.6"
+    wolfy87-eventemitter "~5.1.0"
+
+"@antv/g@~3.1.1":
+  version "3.1.2"
+  resolved "https://registry.yarnpkg.com/@antv/g/-/g-3.1.2.tgz#08b958782f5aeb96f0f49518176a2edcf18980eb"
+  dependencies:
+    "@antv/gl-matrix" "~2.7.1"
+    "@antv/util" "~1.0.11"
+    d3-ease "~1.0.3"
+    d3-interpolate "~1.1.5"
+    d3-timer "~1.0.6"
+    wolfy87-eventemitter "~5.1.0"
+
+"@antv/gl-matrix@~2.7.1":
+  version "2.7.1"
+  resolved "https://registry.yarnpkg.com/@antv/gl-matrix/-/gl-matrix-2.7.1.tgz#acb8e37f7ab3df01345aba4372d7942be42eba14"
+
+"@antv/hierarchy@~0.1.0-beta.2":
+  version "0.1.2"
+  resolved "https://registry.yarnpkg.com/@antv/hierarchy/-/hierarchy-0.1.2.tgz#d736fe5c4cf8ae664ba51bca194a1786c028ad9d"
+
+"@antv/interaction@~0.1.5":
+  version "0.1.5"
+  resolved "https://registry.yarnpkg.com/@antv/interaction/-/interaction-0.1.5.tgz#6587cf7bdc6820826791dcb060baf61d2fdce77e"
+  dependencies:
+    "@antv/g" "3.1.0-beta.6"
+    "@antv/util" "~1.0.11"
+
+"@antv/scale@~0.0.5":
+  version "0.0.8"
+  resolved "https://registry.yarnpkg.com/@antv/scale/-/scale-0.0.8.tgz#abadec0e432c657089c7b17ea019cddc267b4f84"
+  dependencies:
+    "@antv/util" "~1.0.11"
+    fecha "~2.3.3"
+
+"@antv/util@~1.0.11", "@antv/util@~1.0.12":
+  version "1.0.12"
+  resolved "https://registry.yarnpkg.com/@antv/util/-/util-1.0.12.tgz#b55e921f30f1c8410f3e24a2d889e82568c3df38"
+
 "@babel/code-frame@7.0.0-beta.44":
   version "7.0.0-beta.44"
   resolved "https://registry.yarnpkg.com/@babel/code-frame/-/code-frame-7.0.0-beta.44.tgz#2a02643368de80916162be70865c97774f3adbd9"
@@ -653,6 +756,22 @@
   version "1.1.1"
   resolved "https://registry.yarnpkg.com/@nodelib/fs.stat/-/fs.stat-1.1.1.tgz#53f349bb986ab273d601175aa1b25a655ab90ee3"
 
+"@types/d3-format@*":
+  version "1.3.0"
+  resolved "https://registry.yarnpkg.com/@types/d3-format/-/d3-format-1.3.0.tgz#c5e115fac8e6861ce656fe9861892b22f6b0cfcb"
+
+"@types/lodash@*":
+  version "4.14.116"
+  resolved "https://registry.yarnpkg.com/@types/lodash/-/lodash-4.14.116.tgz#5ccf215653e3e8c786a58390751033a9adca0eb9"
+
+"@types/node@*":
+  version "10.7.1"
+  resolved "https://registry.yarnpkg.com/@types/node/-/node-10.7.1.tgz#b704d7c259aa40ee052eec678758a68d07132a2e"
+
+"@types/node@^8.0.53":
+  version "8.10.26"
+  resolved "https://registry.yarnpkg.com/@types/node/-/node-8.10.26.tgz#950e3d4e6b316ba6e1ae4e84d9155aba67f88c2f"
+
 "@vue/babel-preset-app@^3.0.1":
   version "3.0.1"
   resolved "https://registry.yarnpkg.com/@vue/babel-preset-app/-/babel-preset-app-3.0.1.tgz#24188938e93f259f7141a6a1190da9c511d123d8"
@@ -933,6 +1052,10 @@ abbrev@1:
   version "1.1.1"
   resolved "https://registry.yarnpkg.com/abbrev/-/abbrev-1.1.1.tgz#f8f2c887ad10bf67f634f005b6987fed3179aac8"
 
+abs-svg-path@~0.1.1:
+  version "0.1.1"
+  resolved "https://registry.yarnpkg.com/abs-svg-path/-/abs-svg-path-0.1.1.tgz#df601c8e8d2ba10d4a76d625e236a9a39c2723bf"
+
 accepts@~1.3.4, accepts@~1.3.5:
   version "1.3.5"
   resolved "https://registry.yarnpkg.com/accepts/-/accepts-1.3.5.tgz#eb777df6011723a3b14e8a72c0805c8e86746bd2"
@@ -1000,6 +1123,14 @@ ajv@^6.1.0:
     json-schema-traverse "^0.4.1"
     uri-js "^4.2.2"
 
+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"
+  dependencies:
+    kind-of "^3.0.2"
+    longest "^1.0.1"
+    repeat-string "^1.5.2"
+
 alphanum-sort@^1.0.0:
   version "1.0.2"
   resolved "https://registry.yarnpkg.com/alphanum-sort/-/alphanum-sort-1.0.2.tgz#97a1119649b211ad33691d9f9f486a8ec9fbe0a3"
@@ -1609,6 +1740,10 @@ camelcase-keys@^2.0.0:
     camelcase "^2.0.0"
     map-obj "^1.0.0"
 
+camelcase@^1.0.2:
+  version "1.2.1"
+  resolved "https://registry.yarnpkg.com/camelcase/-/camelcase-1.2.1.tgz#9bb5304d2e0b56698b2c758b08a3eaa9daa58a39"
+
 camelcase@^2.0.0:
   version "2.1.1"
   resolved "https://registry.yarnpkg.com/camelcase/-/camelcase-2.1.1.tgz#7c1d16d679a1bbe59ca02cacecfb011e201f5a1f"
@@ -1642,6 +1777,13 @@ caseless@~0.12.0:
   version "0.12.0"
   resolved "https://registry.yarnpkg.com/caseless/-/caseless-0.12.0.tgz#1b681c21ff84033c826543090689420d187151dc"
 
+center-align@^0.1.1:
+  version "0.1.3"
+  resolved "https://registry.yarnpkg.com/center-align/-/center-align-0.1.3.tgz#aa0d32629b6ee972200411cbd4461c907bc2b7ad"
+  dependencies:
+    align-text "^0.1.3"
+    lazy-cache "^1.0.3"
+
 chalk@^1.1.1, chalk@^1.1.3:
   version "1.1.3"
   resolved "https://registry.yarnpkg.com/chalk/-/chalk-1.1.3.tgz#a8115c55e4a702fe4d150abd3872822a7e09fc98"
@@ -1664,6 +1806,10 @@ chardet@^0.4.0:
   version "0.4.2"
   resolved "https://registry.yarnpkg.com/chardet/-/chardet-0.4.2.tgz#b5473b33dc97c424e5d98dc87d55d4d8a29c8bf2"
 
+charenc@~0.0.1:
+  version "0.0.2"
+  resolved "https://registry.yarnpkg.com/charenc/-/charenc-0.0.2.tgz#c0a1d2f3a7092e03774bfa83f14c0fc5790a8667"
+
 check-types@^7.3.0:
   version "7.4.0"
   resolved "https://registry.yarnpkg.com/check-types/-/check-types-7.4.0.tgz#0378ec1b9616ec71f774931a3c6516fad8c152f4"
@@ -1752,6 +1898,14 @@ clipboardy@^1.2.3:
     arch "^2.1.0"
     execa "^0.8.0"
 
+cliui@^2.1.0:
+  version "2.1.0"
+  resolved "https://registry.yarnpkg.com/cliui/-/cliui-2.1.0.tgz#4b475760ff80264c762c3a1719032e91c7fea0d1"
+  dependencies:
+    center-align "^0.1.1"
+    right-align "^0.1.1"
+    wordwrap "0.0.2"
+
 cliui@^3.2.0:
   version "3.2.0"
   resolved "https://registry.yarnpkg.com/cliui/-/cliui-3.2.0.tgz#120601537a916d29940f934da3b48d585a39213d"
@@ -1840,7 +1994,7 @@ combined-stream@1.0.6, combined-stream@~1.0.5, combined-stream@~1.0.6:
   dependencies:
     delayed-stream "~1.0.0"
 
-commander@2.17.x, commander@^2.13.0:
+commander@2, commander@2.17.x, commander@^2.13.0:
   version "2.17.1"
   resolved "https://registry.yarnpkg.com/commander/-/commander-2.17.1.tgz#bd77ab7de6de94205ceacc72f1716d29f20a77bf"
 
@@ -1933,6 +2087,10 @@ content-type@~1.0.4:
   version "1.0.4"
   resolved "https://registry.yarnpkg.com/content-type/-/content-type-1.0.4.tgz#e138cc75e040c727b1966fe5e5f8c9aee256fe3b"
 
+contour_plot@^0.0.1:
+  version "0.0.1"
+  resolved "https://registry.yarnpkg.com/contour_plot/-/contour_plot-0.0.1.tgz#475870f032b8e338412aa5fc507880f0bf495c77"
+
 convert-source-map@^1.1.0:
   version "1.5.1"
   resolved "https://registry.yarnpkg.com/convert-source-map/-/convert-source-map-1.5.1.tgz#b8278097b9bc229365de5c62cf5fcaed8b5599e5"
@@ -2051,6 +2209,10 @@ cross-spawn@^6.0.0:
     shebang-command "^1.2.0"
     which "^1.2.9"
 
+crypt@~0.0.1:
+  version "0.0.2"
+  resolved "https://registry.yarnpkg.com/crypt/-/crypt-0.0.2.tgz#88d7ff7ec0dfb86f713dc87bbb42d044d3e6c41b"
+
 crypto-browserify@^3.11.0:
   version "3.12.0"
   resolved "https://registry.yarnpkg.com/crypto-browserify/-/crypto-browserify-3.12.0.tgz#396cf9f3137f03e4b8e532c58f698254e00f80ec"
@@ -2233,12 +2395,147 @@ cyclist@~0.2.2:
   version "0.2.2"
   resolved "https://registry.yarnpkg.com/cyclist/-/cyclist-0.2.2.tgz#1b33792e11e914a2fd6d6ed6447464444e5fa640"
 
+d3-array@1, d3-array@~1.2.0:
+  version "1.2.1"
+  resolved "https://registry.yarnpkg.com/d3-array/-/d3-array-1.2.1.tgz#d1ca33de2f6ac31efadb8e050a021d7e2396d5dc"
+
+d3-collection@1:
+  version "1.0.4"
+  resolved "https://registry.yarnpkg.com/d3-collection/-/d3-collection-1.0.4.tgz#342dfd12837c90974f33f1cc0a785aea570dcdc2"
+
+d3-color@1:
+  version "1.2.0"
+  resolved "https://registry.yarnpkg.com/d3-color/-/d3-color-1.2.0.tgz#d1ea19db5859c86854586276ec892cf93148459a"
+
+d3-composite-projections@~1.2.0:
+  version "1.2.0"
+  resolved "https://registry.yarnpkg.com/d3-composite-projections/-/d3-composite-projections-1.2.0.tgz#fa0e6f1442f17d04643843a3a883c7d94e0c27c0"
+  dependencies:
+    d3-geo "1.2.4"
+    d3-path "^1.0.1"
+
+d3-dispatch@1:
+  version "1.0.3"
+  resolved "https://registry.yarnpkg.com/d3-dispatch/-/d3-dispatch-1.0.3.tgz#46e1491eaa9b58c358fce5be4e8bed626e7871f8"
+
+d3-dsv@~1.0.5:
+  version "1.0.8"
+  resolved "https://registry.yarnpkg.com/d3-dsv/-/d3-dsv-1.0.8.tgz#907e240d57b386618dc56468bacfe76bf19764ae"
+  dependencies:
+    commander "2"
+    iconv-lite "0.4"
+    rw "1"
+
+d3-ease@1, d3-ease@~1.0.3:
+  version "1.0.3"
+  resolved "https://registry.yarnpkg.com/d3-ease/-/d3-ease-1.0.3.tgz#68bfbc349338a380c44d8acc4fbc3304aa2d8c0e"
+
+d3-format@^1.2.0:
+  version "1.3.0"
+  resolved "https://registry.yarnpkg.com/d3-format/-/d3-format-1.3.0.tgz#a3ac44269a2011cdb87c7b5693040c18cddfff11"
+
+d3-geo-projection@~2.1.2:
+  version "2.1.2"
+  resolved "https://registry.yarnpkg.com/d3-geo-projection/-/d3-geo-projection-2.1.2.tgz#7df8e1e9d046d631c6509f7e531357d4adc24aa3"
+  dependencies:
+    commander "2"
+    d3-array "1"
+    d3-geo "^1.1.0"
+
+d3-geo@1.2.4:
+  version "1.2.4"
+  resolved "https://registry.yarnpkg.com/d3-geo/-/d3-geo-1.2.4.tgz#d179f3baa76e623ef1e0d83693db705b7c599006"
+  dependencies:
+    d3-array "1"
+
+d3-geo@^1.1.0:
+  version "1.10.0"
+  resolved "https://registry.yarnpkg.com/d3-geo/-/d3-geo-1.10.0.tgz#2972d18014f1e38fc1f8bb6d545377bdfb00c9ab"
+  dependencies:
+    d3-array "1"
+
+d3-geo@~1.6.4:
+  version "1.6.4"
+  resolved "https://registry.yarnpkg.com/d3-geo/-/d3-geo-1.6.4.tgz#f20e1e461cb1845f5a8be55ab6f876542a7e3199"
+  dependencies:
+    d3-array "1"
+
+d3-hexjson@~1.0.1:
+  version "1.0.1"
+  resolved "https://registry.yarnpkg.com/d3-hexjson/-/d3-hexjson-1.0.1.tgz#6a23111e8359f1e214f5d0afa379c02b2b67df0b"
+  dependencies:
+    d3-array "1"
+
+d3-hierarchy@~1.1.5:
+  version "1.1.6"
+  resolved "https://registry.yarnpkg.com/d3-hierarchy/-/d3-hierarchy-1.1.6.tgz#842c1372090f870b7ea013ebae5c0c8d9f56229c"
+
+d3-interpolate@1:
+  version "1.2.0"
+  resolved "https://registry.yarnpkg.com/d3-interpolate/-/d3-interpolate-1.2.0.tgz#40d81bd8e959ff021c5ea7545bc79b8d22331c41"
+  dependencies:
+    d3-color "1"
+
+d3-interpolate@~1.1.5:
+  version "1.1.6"
+  resolved "https://registry.yarnpkg.com/d3-interpolate/-/d3-interpolate-1.1.6.tgz#2cf395ae2381804df08aa1bf766b7f97b5f68fb6"
+  dependencies:
+    d3-color "1"
+
+d3-path@1, d3-path@^1.0.1:
+  version "1.0.5"
+  resolved "https://registry.yarnpkg.com/d3-path/-/d3-path-1.0.5.tgz#241eb1849bd9e9e8021c0d0a799f8a0e8e441764"
+
+d3-sankey@~0.7.1:
+  version "0.7.1"
+  resolved "https://registry.yarnpkg.com/d3-sankey/-/d3-sankey-0.7.1.tgz#d229832268fc69a7fec84803e96c2256a614c521"
+  dependencies:
+    d3-array "1"
+    d3-collection "1"
+    d3-shape "^1.2.0"
+
+d3-selection@^1.0.2, d3-selection@^1.1.0:
+  version "1.3.0"
+  resolved "https://registry.yarnpkg.com/d3-selection/-/d3-selection-1.3.0.tgz#d53772382d3dc4f7507bfb28bcd2d6aed2a0ad6d"
+
+d3-shape@^1.2.0:
+  version "1.2.0"
+  resolved "https://registry.yarnpkg.com/d3-shape/-/d3-shape-1.2.0.tgz#45d01538f064bafd05ea3d6d2cb748fd8c41f777"
+  dependencies:
+    d3-path "1"
+
+d3-timer@1, d3-timer@~1.0.6:
+  version "1.0.7"
+  resolved "https://registry.yarnpkg.com/d3-timer/-/d3-timer-1.0.7.tgz#df9650ca587f6c96607ff4e60cc38229e8dd8531"
+
+d3-transition@^1.0.1:
+  version "1.1.1"
+  resolved "https://registry.yarnpkg.com/d3-transition/-/d3-transition-1.1.1.tgz#d8ef89c3b848735b060e54a39b32aaebaa421039"
+  dependencies:
+    d3-color "1"
+    d3-dispatch "1"
+    d3-ease "1"
+    d3-interpolate "1"
+    d3-selection "^1.1.0"
+    d3-timer "1"
+
+d3-voronoi@~1.1.2:
+  version "1.1.2"
+  resolved "https://registry.yarnpkg.com/d3-voronoi/-/d3-voronoi-1.1.2.tgz#1687667e8f13a2d158c80c1480c5a29cb0d8973c"
+
 d@1:
   version "1.0.0"
   resolved "https://registry.yarnpkg.com/d/-/d-1.0.0.tgz#754bb5bfe55451da69a58b94d45f4c5b0462d58f"
   dependencies:
     es5-ext "^0.10.9"
 
+dagre@~0.8.2:
+  version "0.8.2"
+  resolved "https://registry.yarnpkg.com/dagre/-/dagre-0.8.2.tgz#755b79f4d5499d63cf74c3368fb08add93eceafe"
+  dependencies:
+    graphlib "^2.1.5"
+    lodash "^4.17.4"
+
 dashdash@^1.12.0:
   version "1.14.1"
   resolved "https://registry.yarnpkg.com/dashdash/-/dashdash-1.14.1.tgz#853cfa0f7cbe2fed5de20326b8dd581035f6e2f0"
@@ -2265,7 +2562,7 @@ debug@^3.1.0:
   dependencies:
     ms "2.0.0"
 
-decamelize@^1.1.1, decamelize@^1.1.2:
+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"
 
@@ -2273,7 +2570,7 @@ 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-equal@^1.0.1:
+deep-equal@^1.0.1, deep-equal@~1.0.1:
   version "1.0.1"
   resolved "https://registry.yarnpkg.com/deep-equal/-/deep-equal-1.0.1.tgz#f5d260292b660e084eff4cdbc9f08ad3247448b5"
 
@@ -2320,6 +2617,10 @@ define-property@^2.0.2:
     is-descriptor "^1.0.2"
     isobject "^3.0.1"
 
+defined@~1.0.0:
+  version "1.0.0"
+  resolved "https://registry.yarnpkg.com/defined/-/defined-1.0.0.tgz#c98d9bcef75674188e110969151199e39b1fa693"
+
 del@^2.0.2:
   version "2.2.2"
   resolved "https://registry.yarnpkg.com/del/-/del-2.2.2.tgz#c12c981d067846c84bcaf862cff930d907ffd1a8"
@@ -2580,7 +2881,7 @@ error-stack-parser@^2.0.0:
   dependencies:
     stackframe "^1.0.4"
 
-es-abstract@^1.4.3, es-abstract@^1.5.1, es-abstract@^1.6.1, es-abstract@^1.7.0:
+es-abstract@^1.4.3, es-abstract@^1.5.0, es-abstract@^1.5.1, es-abstract@^1.6.1, es-abstract@^1.7.0:
   version "1.12.0"
   resolved "https://registry.yarnpkg.com/es-abstract/-/es-abstract-1.12.0.tgz#9dbbdd27c6856f0001421ca18782d786bf8a6165"
   dependencies:
@@ -2963,6 +3264,10 @@ faye-websocket@~0.11.0:
   dependencies:
     websocket-driver ">=0.5.1"
 
+fecha@~2.3.3:
+  version "2.3.3"
+  resolved "https://registry.yarnpkg.com/fecha/-/fecha-2.3.3.tgz#948e74157df1a32fd1b12c3a3c3cdcb6ec9d96cd"
+
 figures@^2.0.0:
   version "2.0.0"
   resolved "https://registry.yarnpkg.com/figures/-/figures-2.0.0.tgz#3ab1a2d2a62c8bfb431a0c94cb797a2fce27c962"
@@ -3071,12 +3376,28 @@ flush-write-stream@^1.0.0:
     inherits "^2.0.1"
     readable-stream "^2.0.4"
 
+fmin@0.0.2:
+  version "0.0.2"
+  resolved "https://registry.yarnpkg.com/fmin/-/fmin-0.0.2.tgz#59bbb40d43ffdc1c94cd00a568c41f95f1973017"
+  dependencies:
+    contour_plot "^0.0.1"
+    json2module "^0.0.3"
+    rollup "^0.25.8"
+    tape "^4.5.1"
+    uglify-js "^2.6.2"
+
 follow-redirects@^1.0.0, follow-redirects@^1.3.0:
   version "1.5.5"
   resolved "https://registry.yarnpkg.com/follow-redirects/-/follow-redirects-1.5.5.tgz#3c143ca599a2e22e62876687d68b23d55bad788b"
   dependencies:
     debug "^3.1.0"
 
+for-each@~0.3.3:
+  version "0.3.3"
+  resolved "https://registry.yarnpkg.com/for-each/-/for-each-0.3.3.tgz#69b447e88a0a5d32c3e7084f3f1710034b21376e"
+  dependencies:
+    is-callable "^1.1.3"
+
 for-in@^0.1.3:
   version "0.1.8"
   resolved "https://registry.yarnpkg.com/for-in/-/for-in-0.1.8.tgz#d8773908e31256109952b1fdb9b3fa867d2775e1"
@@ -3181,7 +3502,7 @@ fstream@^1.0.0, fstream@^1.0.2:
     mkdirp ">=0.5 0"
     rimraf "2"
 
-function-bind@^1.0.2, function-bind@^1.1.0, function-bind@^1.1.1:
+function-bind@^1.0.2, function-bind@^1.1.0, function-bind@^1.1.1, function-bind@~1.1.1:
   version "1.1.1"
   resolved "https://registry.yarnpkg.com/function-bind/-/function-bind-1.1.1.tgz#a56899d3ea3c9bab874bb9773b7c5ede92f4895d"
 
@@ -3264,7 +3585,7 @@ glob@^6.0.4:
     once "^1.3.0"
     path-is-absolute "^1.0.0"
 
-glob@^7.0.0, glob@^7.0.3, glob@^7.0.5, glob@^7.1.2, glob@~7.1.1:
+glob@^7.0.0, glob@^7.0.3, glob@^7.0.5, glob@^7.1.2, glob@~7.1.1, glob@~7.1.2:
   version "7.1.2"
   resolved "https://registry.yarnpkg.com/glob/-/glob-7.1.2.tgz#c19c9df9a028702d678612384a6552404c636d15"
   dependencies:
@@ -3335,6 +3656,12 @@ graceful-fs@^4.1.11, graceful-fs@^4.1.2, graceful-fs@^4.1.6:
   version "4.1.11"
   resolved "https://registry.yarnpkg.com/graceful-fs/-/graceful-fs-4.1.11.tgz#0e8bdfe4d1ddb8854d64e04ea7c00e2a026e5658"
 
+graphlib@^2.1.5:
+  version "2.1.5"
+  resolved "https://registry.yarnpkg.com/graphlib/-/graphlib-2.1.5.tgz#6afe1afcc5148555ec799e499056795bd6938c87"
+  dependencies:
+    lodash "^4.11.1"
+
 gzip-size@^4.1.0:
   version "4.1.0"
   resolved "https://registry.yarnpkg.com/gzip-size/-/gzip-size-4.1.0.tgz#8ae096257eabe7d69c45be2b67c448124ffb517c"
@@ -3409,7 +3736,7 @@ has-values@^1.0.0:
     is-number "^3.0.0"
     kind-of "^4.0.0"
 
-has@^1.0.0, has@^1.0.1:
+has@^1.0.0, has@^1.0.1, has@~1.0.3:
   version "1.0.3"
   resolved "https://registry.yarnpkg.com/has/-/has-1.0.3.tgz#722d7cbfc1f6aa8241f16dd814e011e1f41e8796"
   dependencies:
@@ -3570,16 +3897,16 @@ https-browserify@^1.0.0:
   version "1.0.0"
   resolved "https://registry.yarnpkg.com/https-browserify/-/https-browserify-1.0.0.tgz#ec06c10e0a34c0f2faf199f7fd7fc78fffd03c73"
 
-iconv-lite@0.4.19:
-  version "0.4.19"
-  resolved "https://registry.yarnpkg.com/iconv-lite/-/iconv-lite-0.4.19.tgz#f7468f60135f5e5dad3399c0a81be9a1603a082b"
-
-iconv-lite@^0.4.17, iconv-lite@^0.4.4:
+iconv-lite@0.4, iconv-lite@^0.4.17, iconv-lite@^0.4.4:
   version "0.4.23"
   resolved "https://registry.yarnpkg.com/iconv-lite/-/iconv-lite-0.4.23.tgz#297871f63be507adcfbfca715d0cd0eed84e9a63"
   dependencies:
     safer-buffer ">= 2.1.2 < 3"
 
+iconv-lite@0.4.19:
+  version "0.4.19"
+  resolved "https://registry.yarnpkg.com/iconv-lite/-/iconv-lite-0.4.19.tgz#f7468f60135f5e5dad3399c0a81be9a1603a082b"
+
 icss-replace-symbols@^1.1.0:
   version "1.1.0"
   resolved "https://registry.yarnpkg.com/icss-replace-symbols/-/icss-replace-symbols-1.1.0.tgz#06ea6f83679a7749e386cfe1fe812ae5db223ded"
@@ -3741,7 +4068,7 @@ is-binary-path@^1.0.0:
   dependencies:
     binary-extensions "^1.0.0"
 
-is-buffer@^1.1.5:
+is-buffer@^1.1.5, is-buffer@~1.1.1:
   version "1.1.6"
   resolved "https://registry.yarnpkg.com/is-buffer/-/is-buffer-1.1.6.tgz#efaa2ea9daa0d7ab2ea13a97b2b8ad51fefbe8be"
 
@@ -3968,7 +4295,7 @@ is-wsl@^1.1.0:
   version "1.1.0"
   resolved "https://registry.yarnpkg.com/is-wsl/-/is-wsl-1.1.0.tgz#1f16e4aa22b04d1336b66188a66af3c600c3a66d"
 
-isarray@0.0.1:
+isarray@0.0.1, isarray@~0.0.1:
   version "0.0.1"
   resolved "https://registry.yarnpkg.com/isarray/-/isarray-0.0.1.tgz#8a18acfca9a8f4177e09abfc6038939b05d1eedf"
 
@@ -4088,6 +4415,12 @@ json-stringify-safe@~5.0.1:
   version "5.0.1"
   resolved "https://registry.yarnpkg.com/json-stringify-safe/-/json-stringify-safe-5.0.1.tgz#1296a2d58fd45f19a0f6ce01d65701e2c735b6eb"
 
+json2module@^0.0.3:
+  version "0.0.3"
+  resolved "https://registry.yarnpkg.com/json2module/-/json2module-0.0.3.tgz#00fb5f4a9b7adfc3f0647c29cb17bcd1979be9b2"
+  dependencies:
+    rw "^1.3.2"
+
 json2mq@^0.2.0:
   version "0.2.0"
   resolved "https://registry.yarnpkg.com/json2mq/-/json2mq-0.2.0.tgz#b637bd3ba9eabe122c83e9720483aeb10d2c904a"
@@ -4158,6 +4491,10 @@ launch-editor@^2.2.1:
     chalk "^2.3.0"
     shell-quote "^1.6.1"
 
+lazy-cache@^1.0.3:
+  version "1.0.4"
+  resolved "https://registry.yarnpkg.com/lazy-cache/-/lazy-cache-1.0.4.tgz#a1d78fc3a50474cb80845d3b3b6e1da49a446e8e"
+
 lcid@^1.0.0:
   version "1.0.0"
   resolved "https://registry.yarnpkg.com/lcid/-/lcid-1.0.0.tgz#308accafa0bc483a3867b4b6f2b9506251d1b835"
@@ -4260,7 +4597,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.13.1, lodash@^4.17.10, lodash@^4.17.3, lodash@^4.17.4, lodash@^4.17.5, lodash@^4.2.0, lodash@^4.3.0, lodash@~4.17.10:
+lodash@^4.0.0, lodash@^4.11.1, lodash@^4.13.1, lodash@^4.17.10, lodash@^4.17.3, lodash@^4.17.4, lodash@^4.17.5, lodash@^4.2.0, lodash@^4.3.0, lodash@~4.17.10, lodash@~4.17.4:
   version "4.17.10"
   resolved "https://registry.yarnpkg.com/lodash/-/lodash-4.17.10.tgz#1b7793cf7259ea38fb3661d4d38b3260af8ae4e7"
 
@@ -4289,6 +4626,10 @@ long@^3.2.0:
   version "3.2.0"
   resolved "https://registry.yarnpkg.com/long/-/long-3.2.0.tgz#d821b7138ca1cb581c172990ef14db200b5c474b"
 
+longest@^1.0.1:
+  version "1.0.1"
+  resolved "https://registry.yarnpkg.com/longest/-/longest-1.0.1.tgz#30a0b2da38f73770e8294a0d22e6625ed77d0097"
+
 loose-envify@^1.0.0:
   version "1.4.0"
   resolved "https://registry.yarnpkg.com/loose-envify/-/loose-envify-1.4.0.tgz#71ee51fa7be4caec1a63839f7e682d8132d30caf"
@@ -4348,6 +4689,14 @@ md5.js@^1.3.4:
     hash-base "^3.0.0"
     inherits "^2.0.1"
 
+md5@^2.2.1:
+  version "2.2.1"
+  resolved "https://registry.yarnpkg.com/md5/-/md5-2.2.1.tgz#53ab38d5fe3c8891ba465329ea23fac0540126f9"
+  dependencies:
+    charenc "~0.0.1"
+    crypt "~0.0.1"
+    is-buffer "~1.1.1"
+
 mdn-data@^1.0.0, mdn-data@~1.1.0:
   version "1.1.4"
   resolved "https://registry.yarnpkg.com/mdn-data/-/mdn-data-1.1.4.tgz#50b5d4ffc4575276573c4eedb8780812a8419f01"
@@ -4493,7 +4842,7 @@ minimist@0.0.8:
   version "0.0.8"
   resolved "https://registry.yarnpkg.com/minimist/-/minimist-0.0.8.tgz#857fcabfc3397d2625b8228262e86aa7a011b05d"
 
-minimist@^1.1.3, minimist@^1.2.0:
+minimist@^1.1.3, minimist@^1.2.0, minimist@~1.2.0:
   version "1.2.0"
   resolved "https://registry.yarnpkg.com/minimist/-/minimist-1.2.0.tgz#a35008b20f41383eec1fb914f4cd5df79a264284"
 
@@ -4843,6 +5192,10 @@ object-hash@^1.1.4:
   version "1.3.0"
   resolved "https://registry.yarnpkg.com/object-hash/-/object-hash-1.3.0.tgz#76d9ba6ff113cf8efc0d996102851fe6723963e2"
 
+object-inspect@~1.6.0:
+  version "1.6.0"
+  resolved "https://registry.yarnpkg.com/object-inspect/-/object-inspect-1.6.0.tgz#c70b6cbf72f274aab4c34c0c82f5167bf82cf15b"
+
 object-keys@^1.0.11, object-keys@^1.0.12:
   version "1.0.12"
   resolved "https://registry.yarnpkg.com/object-keys/-/object-keys-1.0.12.tgz#09c53855377575310cca62f55bb334abff7b3ed2"
@@ -5068,6 +5421,10 @@ parse-json@^4.0.0:
     error-ex "^1.3.1"
     json-parse-better-errors "^1.0.1"
 
+parse-svg-path@~0.1.1:
+  version "0.1.2"
+  resolved "https://registry.yarnpkg.com/parse-svg-path/-/parse-svg-path-0.1.2.tgz#7a7ec0d1eb06fa5325c7d3e009b859a09b5d49eb"
+
 parseurl@~1.3.2:
   version "1.3.2"
   resolved "https://registry.yarnpkg.com/parseurl/-/parseurl-1.3.2.tgz#fc289d4ed8993119460c156253262cdc8de65bf3"
@@ -5176,6 +5533,14 @@ pluralize@^7.0.0:
   version "7.0.0"
   resolved "https://registry.yarnpkg.com/pluralize/-/pluralize-7.0.0.tgz#298b89df8b93b0221dbf421ad2b1b1ea23fc6777"
 
+point-at-length@~1.0.2:
+  version "1.0.2"
+  resolved "https://registry.yarnpkg.com/point-at-length/-/point-at-length-1.0.2.tgz#9176d8d6d7c8162f12b646f707db9f0ea728125e"
+  dependencies:
+    abs-svg-path "~0.1.1"
+    isarray "~0.0.1"
+    parse-svg-path "~0.1.1"
+
 portfinder@^1.0.13, portfinder@^1.0.9:
   version "1.0.17"
   resolved "https://registry.yarnpkg.com/portfinder/-/portfinder-1.0.17.tgz#a8a1691143e46c4735edefcf4fbcccedad26456a"
@@ -5791,6 +6156,10 @@ regjsparser@^0.3.0:
   dependencies:
     jsesc "~0.5.0"
 
+regression@~2.0.0:
+  version "2.0.1"
+  resolved "https://registry.yarnpkg.com/regression/-/regression-2.0.1.tgz#8d29c3e8224a10850c35e337e85a8b2fac3b0c87"
+
 relateurl@0.2.x:
   version "0.2.7"
   resolved "https://registry.yarnpkg.com/relateurl/-/relateurl-0.2.7.tgz#54dbf377e51440aca90a4cd274600d3ff2d888a9"
@@ -5938,6 +6307,12 @@ resolve@^1.3.2:
   dependencies:
     path-parse "^1.0.5"
 
+resolve@~1.7.1:
+  version "1.7.1"
+  resolved "https://registry.yarnpkg.com/resolve/-/resolve-1.7.1.tgz#aadd656374fd298aee895bc026b8297418677fd3"
+  dependencies:
+    path-parse "^1.0.5"
+
 restore-cursor@^2.0.0:
   version "2.0.0"
   resolved "https://registry.yarnpkg.com/restore-cursor/-/restore-cursor-2.0.0.tgz#9f7ee287f82fd326d4fd162923d62129eee0dfaf"
@@ -5945,6 +6320,12 @@ restore-cursor@^2.0.0:
     onetime "^2.0.0"
     signal-exit "^3.0.2"
 
+resumer@~0.0.0:
+  version "0.0.0"
+  resolved "https://registry.yarnpkg.com/resumer/-/resumer-0.0.0.tgz#f1e8f461e4064ba39e82af3cdc2a8c893d076759"
+  dependencies:
+    through "~2.3.4"
+
 ret@~0.1.10:
   version "0.1.15"
   resolved "https://registry.yarnpkg.com/ret/-/ret-0.1.15.tgz#b8a4825d5bdb1fc3f6f53c2bc33f81388681c7bc"
@@ -5957,6 +6338,12 @@ rgba-regex@^1.0.0:
   version "1.0.0"
   resolved "https://registry.yarnpkg.com/rgba-regex/-/rgba-regex-1.0.0.tgz#43374e2e2ca0968b0ef1523460b7d730ff22eeb3"
 
+right-align@^0.1.1:
+  version "0.1.3"
+  resolved "https://registry.yarnpkg.com/right-align/-/right-align-0.1.3.tgz#61339b722fe6a3515689210d24e14c96148613ef"
+  dependencies:
+    align-text "^0.1.1"
+
 rimraf@2, rimraf@^2.2.8, rimraf@^2.5.4, rimraf@^2.6.1, rimraf@^2.6.2:
   version "2.6.2"
   resolved "https://registry.yarnpkg.com/rimraf/-/rimraf-2.6.2.tgz#2ed8150d24a16ea8651e6d6ef0f47c4158ce7a36"
@@ -5970,6 +6357,14 @@ ripemd160@^2.0.0, ripemd160@^2.0.1:
     hash-base "^3.0.0"
     inherits "^2.0.1"
 
+rollup@^0.25.8:
+  version "0.25.8"
+  resolved "https://registry.yarnpkg.com/rollup/-/rollup-0.25.8.tgz#bf6ce83b87510d163446eeaa577ed6a6fc5835e0"
+  dependencies:
+    chalk "^1.1.1"
+    minimist "^1.2.0"
+    source-map-support "^0.3.2"
+
 run-async@^2.2.0:
   version "2.3.0"
   resolved "https://registry.yarnpkg.com/run-async/-/run-async-2.3.0.tgz#0371ab4ae0bdd720d4166d7dfda64ff7a445a6c0"
@@ -5982,6 +6377,10 @@ run-queue@^1.0.0, run-queue@^1.0.3:
   dependencies:
     aproba "^1.1.1"
 
+rw@1, rw@^1.3.2:
+  version "1.3.3"
+  resolved "https://registry.yarnpkg.com/rw/-/rw-1.3.3.tgz#3f862dfa91ab766b14885ef4d01124bfda074fb4"
+
 rx-lite-aggregates@^4.0.8:
   version "4.0.8"
   resolved "https://registry.yarnpkg.com/rx-lite-aggregates/-/rx-lite-aggregates-4.0.8.tgz#753b87a89a11c95467c4ac1626c4efc4e05c67be"
@@ -6201,6 +6600,10 @@ signal-exit@^3.0.0, signal-exit@^3.0.2:
   version "3.0.2"
   resolved "https://registry.yarnpkg.com/signal-exit/-/signal-exit-3.0.2.tgz#b5fdc08f1287ea1178628e415e25132b73646c6d"
 
+simple-statistics@~4.1.0:
+  version "4.1.1"
+  resolved "https://registry.yarnpkg.com/simple-statistics/-/simple-statistics-4.1.1.tgz#533c48d48336ba3d350d8135f20fa7138acb0c7d"
+
 simple-swizzle@^0.2.2:
   version "0.2.2"
   resolved "https://registry.yarnpkg.com/simple-swizzle/-/simple-swizzle-0.2.2.tgz#a4da6b635ffcccca33f70d17cb92592de95e557a"
@@ -6280,17 +6683,29 @@ source-map-resolve@^0.5.0:
     source-map-url "^0.4.0"
     urix "^0.1.0"
 
+source-map-support@^0.3.2:
+  version "0.3.3"
+  resolved "https://registry.yarnpkg.com/source-map-support/-/source-map-support-0.3.3.tgz#34900977d5ba3f07c7757ee72e73bb1a9b53754f"
+  dependencies:
+    source-map "0.1.32"
+
 source-map-url@^0.4.0:
   version "0.4.0"
   resolved "https://registry.yarnpkg.com/source-map-url/-/source-map-url-0.4.0.tgz#3e935d7ddd73631b97659956d55128e87b5084a3"
 
+source-map@0.1.32:
+  version "0.1.32"
+  resolved "https://registry.yarnpkg.com/source-map/-/source-map-0.1.32.tgz#c8b6c167797ba4740a8ea33252162ff08591b266"
+  dependencies:
+    amdefine ">=0.0.4"
+
 source-map@^0.4.2:
   version "0.4.4"
   resolved "https://registry.yarnpkg.com/source-map/-/source-map-0.4.4.tgz#eba4f5da9c0dc999de68032d8b4f76173652036b"
   dependencies:
     amdefine ">=0.0.4"
 
-source-map@^0.5.0, source-map@^0.5.3, source-map@^0.5.6:
+source-map@^0.5.0, source-map@^0.5.3, source-map@^0.5.6, source-map@~0.5.1:
   version "0.5.7"
   resolved "https://registry.yarnpkg.com/source-map/-/source-map-0.5.7.tgz#8a039d2d1021d22d1ea14c80d8ea468ba2ef3fcc"
 
@@ -6474,6 +6889,14 @@ string.prototype.padstart@^3.0.0:
     es-abstract "^1.4.3"
     function-bind "^1.0.2"
 
+string.prototype.trim@~1.1.2:
+  version "1.1.2"
+  resolved "https://registry.yarnpkg.com/string.prototype.trim/-/string.prototype.trim-1.1.2.tgz#d04de2c89e137f4d7d206f086b5ed2fae6be8cea"
+  dependencies:
+    define-properties "^1.1.2"
+    es-abstract "^1.5.0"
+    function-bind "^1.0.2"
+
 string_decoder@^1.0.0, string_decoder@~1.1.1:
   version "1.1.1"
   resolved "https://registry.yarnpkg.com/string_decoder/-/string_decoder-1.1.1.tgz#9cf1611ba62685d7030ae9e4ba34149c3af03fc8"
@@ -6572,6 +6995,24 @@ tapable@^1.0.0:
   version "1.0.0"
   resolved "https://registry.yarnpkg.com/tapable/-/tapable-1.0.0.tgz#cbb639d9002eed9c6b5975eb20598d7936f1f9f2"
 
+tape@^4.5.1:
+  version "4.9.1"
+  resolved "https://registry.yarnpkg.com/tape/-/tape-4.9.1.tgz#1173d7337e040c76fbf42ec86fcabedc9b3805c9"
+  dependencies:
+    deep-equal "~1.0.1"
+    defined "~1.0.0"
+    for-each "~0.3.3"
+    function-bind "~1.1.1"
+    glob "~7.1.2"
+    has "~1.0.3"
+    inherits "~2.0.3"
+    minimist "~1.2.0"
+    object-inspect "~1.6.0"
+    resolve "~1.7.1"
+    resumer "~0.0.0"
+    string.prototype.trim "~1.1.2"
+    through "~2.3.8"
+
 tar@^2.0.0:
   version "2.2.1"
   resolved "https://registry.yarnpkg.com/tar/-/tar-2.2.1.tgz#8e4d2a256c0e2185c6b18ad694aec968b83cb1d1"
@@ -6611,7 +7052,7 @@ through2@^2.0.0:
     readable-stream "^2.1.5"
     xtend "~4.0.1"
 
-through@^2.3.6:
+through@^2.3.6, through@~2.3.4, through@~2.3.8:
   version "2.3.8"
   resolved "https://registry.yarnpkg.com/through/-/through-2.3.8.tgz#0dd4c9ffaabc357960b1b724115d7e0e86a2e1f5"
 
@@ -6671,6 +7112,12 @@ topo@3.x.x:
   dependencies:
     hoek "5.x.x"
 
+topojson-client@~3.0.0:
+  version "3.0.0"
+  resolved "https://registry.yarnpkg.com/topojson-client/-/topojson-client-3.0.0.tgz#1f99293a77ef42a448d032a81aa982b73f360d2f"
+  dependencies:
+    commander "2"
+
 toposort@^1.0.0:
   version "1.0.7"
   resolved "https://registry.yarnpkg.com/toposort/-/toposort-1.0.7.tgz#2e68442d9f64ec720b8cc89e6443ac6caa950029"
@@ -6755,6 +7202,19 @@ uglify-js@3.4.x:
     commander "~2.16.0"
     source-map "~0.6.1"
 
+uglify-js@^2.6.2:
+  version "2.8.29"
+  resolved "https://registry.yarnpkg.com/uglify-js/-/uglify-js-2.8.29.tgz#29c5733148057bb4e1f75df35b7a9cb72e6a59dd"
+  dependencies:
+    source-map "~0.5.1"
+    yargs "~3.10.0"
+  optionalDependencies:
+    uglify-to-browserify "~1.0.0"
+
+uglify-to-browserify@~1.0.0:
+  version "1.0.2"
+  resolved "https://registry.yarnpkg.com/uglify-to-browserify/-/uglify-to-browserify-1.0.2.tgz#6e0924d6bda6b5afe349e39a6d632850a0f882b7"
+
 uglifyjs-webpack-plugin@^1.2.4, uglifyjs-webpack-plugin@^1.2.7:
   version "1.3.0"
   resolved "https://registry.yarnpkg.com/uglifyjs-webpack-plugin/-/uglifyjs-webpack-plugin-1.3.0.tgz#75f548160858163a08643e086d5fefe18a5d67de"
@@ -6937,6 +7397,14 @@ vendors@^1.0.0:
   version "1.0.2"
   resolved "https://registry.yarnpkg.com/vendors/-/vendors-1.0.2.tgz#7fcb5eef9f5623b156bcea89ec37d63676f21801"
 
+venn.js@~0.2.20:
+  version "0.2.20"
+  resolved "https://registry.yarnpkg.com/venn.js/-/venn.js-0.2.20.tgz#3f0e50cc75cba1f58692a8a32f67bd7aaf1aa6fa"
+  dependencies:
+    d3-selection "^1.0.2"
+    d3-transition "^1.0.1"
+    fmin "0.0.2"
+
 verror@1.10.0:
   version "1.10.0"
   resolved "https://registry.yarnpkg.com/verror/-/verror-1.10.0.tgz#3a105ca17053af55d6e270c1f8288682e18da400"
@@ -6945,6 +7413,27 @@ verror@1.10.0:
     core-util-is "1.0.2"
     extsprintf "^1.2.0"
 
+viser-vue@^2.3.0:
+  version "2.3.0"
+  resolved "https://registry.yarnpkg.com/viser-vue/-/viser-vue-2.3.0.tgz#36a079af42c3ca4e7969a793932196b7a7a18079"
+  dependencies:
+    "@types/node" "*"
+    viser "^2.0.0"
+    vue "^2.5.3"
+
+viser@^2.0.0:
+  version "2.3.0"
+  resolved "https://registry.yarnpkg.com/viser/-/viser-2.3.0.tgz#d9c9dec5b21c04d007d3536acdecdf14f427a25c"
+  dependencies:
+    "@antv/g2" "^3.2.0"
+    "@antv/g2-brush" "^0.0.2"
+    "@antv/g2-plugin-slider" "^2.0.2"
+    "@types/d3-format" "*"
+    "@types/lodash" "*"
+    "@types/node" "^8.0.53"
+    d3-format "^1.2.0"
+    lodash "^4.17.4"
+
 vm-browserify@0.0.4:
   version "0.0.4"
   resolved "https://registry.yarnpkg.com/vm-browserify/-/vm-browserify-0.0.4.tgz#5d7ea45bbef9e4a6ff65f95438e0a87c357d5a73"
@@ -6998,7 +7487,7 @@ vue-template-es2015-compiler@^1.6.0:
   version "1.6.0"
   resolved "https://registry.yarnpkg.com/vue-template-es2015-compiler/-/vue-template-es2015-compiler-1.6.0.tgz#dc42697133302ce3017524356a6c61b7b69b4a18"
 
-vue@^2.5.17:
+vue@^2.5.17, vue@^2.5.3:
   version "2.5.17"
   resolved "https://registry.yarnpkg.com/vue/-/vue-2.5.17.tgz#0f8789ad718be68ca1872629832ed533589c6ada"
 
@@ -7184,6 +7673,18 @@ wide-align@^1.1.0:
   dependencies:
     string-width "^1.0.2 || 2"
 
+window-size@0.1.0:
+  version "0.1.0"
+  resolved "https://registry.yarnpkg.com/window-size/-/window-size-0.1.0.tgz#5438cd2ea93b202efa3a19fe8887aee7c94f9c9d"
+
+wolfy87-eventemitter@~5.1.0:
+  version "5.1.0"
+  resolved "https://registry.yarnpkg.com/wolfy87-eventemitter/-/wolfy87-eventemitter-5.1.0.tgz#35c1ac0dd1ac0c15e35d981508fc22084a13a011"
+
+wordwrap@0.0.2:
+  version "0.0.2"
+  resolved "https://registry.yarnpkg.com/wordwrap/-/wordwrap-0.0.2.tgz#b79669bb42ecb409f83d583cad52ca17eaa1643f"
+
 wordwrap@~1.0.0:
   version "1.0.0"
   resolved "https://registry.yarnpkg.com/wordwrap/-/wordwrap-1.0.0.tgz#27584810891456a4171c8d0226441ade90cbcaeb"
@@ -7285,6 +7786,15 @@ yargs@^7.0.0:
     y18n "^3.2.1"
     yargs-parser "^5.0.0"
 
+yargs@~3.10.0:
+  version "3.10.0"
+  resolved "https://registry.yarnpkg.com/yargs/-/yargs-3.10.0.tgz#f7ee7bd857dd7c1d2d38c0e74efbd681d1431fd1"
+  dependencies:
+    camelcase "^1.0.2"
+    cliui "^2.1.0"
+    decamelize "^1.0.0"
+    window-size "0.1.0"
+
 yorkie@^2.0.0:
   version "2.0.0"
   resolved "https://registry.yarnpkg.com/yorkie/-/yorkie-2.0.0.tgz#92411912d435214e12c51c2ae1093e54b6bb83d9"

Some files were not shown because too many files changed in this diff