Repository: Liwengbin/vue-task-node Branch: master Commit: 5308561573f1 Files: 85 Total size: 190.5 KB Directory structure: gitextract_ct1001j5/ ├── .babelrc ├── .editorconfig ├── .eslintignore ├── .eslintrc.js ├── .gitignore ├── .postcssrc.js ├── README.md ├── build/ │ ├── build.js │ ├── check-versions.js │ ├── dist/ │ │ ├── css/ │ │ │ └── vnode.css │ │ └── vue-task-node.js │ ├── utils.js │ ├── vue-loader.conf.js │ ├── webpack.base.conf.js │ ├── webpack.dev.conf.js │ └── webpack.prod.conf.js ├── config/ │ ├── dev.env.js │ ├── index.js │ ├── prod.env.js │ └── test.env.js ├── index.html ├── package.json ├── src/ │ ├── App.vue │ ├── lib/ │ │ ├── components/ │ │ │ ├── depend/ │ │ │ │ ├── ModelTree.vue │ │ │ │ ├── TreeNode.vue │ │ │ │ └── index.js │ │ │ ├── node/ │ │ │ │ ├── README.md │ │ │ │ ├── common/ │ │ │ │ │ ├── common.vue │ │ │ │ │ ├── incommonls.vue │ │ │ │ │ ├── index.js │ │ │ │ │ └── outcommonls.vue │ │ │ │ ├── index.js │ │ │ │ ├── initial/ │ │ │ │ │ ├── index.js │ │ │ │ │ └── initial.vue │ │ │ │ └── node.vue │ │ │ ├── nodemodel/ │ │ │ │ ├── index.js │ │ │ │ └── nodemodel.vue │ │ │ ├── path/ │ │ │ │ ├── README.md │ │ │ │ ├── curvepath.vue │ │ │ │ ├── index.js │ │ │ │ └── tline.vue │ │ │ ├── port/ │ │ │ │ ├── README.md │ │ │ │ ├── index.js │ │ │ │ ├── inport.vue │ │ │ │ └── outport.vue │ │ │ └── workarea/ │ │ │ ├── index.js │ │ │ └── workarea.vue │ │ ├── index.js │ │ ├── mixins/ │ │ │ ├── README.md │ │ │ ├── node.js │ │ │ └── tool.js │ │ ├── store/ │ │ │ └── index.js │ │ ├── styles/ │ │ │ ├── common/ │ │ │ │ ├── base.less │ │ │ │ ├── iconfont/ │ │ │ │ │ ├── ionicons-font.less │ │ │ │ │ ├── ionicons-icons.less │ │ │ │ │ ├── ionicons-variables.less │ │ │ │ │ └── ionicons.less │ │ │ │ └── index.less │ │ │ ├── components/ │ │ │ │ ├── index.less │ │ │ │ ├── modeltree.less │ │ │ │ ├── node/ │ │ │ │ │ ├── common/ │ │ │ │ │ │ ├── common.less │ │ │ │ │ │ ├── incommonls.less │ │ │ │ │ │ ├── index.less │ │ │ │ │ │ └── outcommonls.less │ │ │ │ │ ├── initial/ │ │ │ │ │ │ └── initial.less │ │ │ │ │ └── node.less │ │ │ │ ├── nodemodel.less │ │ │ │ ├── port.less │ │ │ │ ├── tline.less │ │ │ │ └── workarea.less │ │ │ ├── custom.less │ │ │ └── index.less │ │ └── utils/ │ │ ├── firefoxCompatible.js │ │ ├── line.js │ │ └── tools.js │ └── main.js ├── static/ │ └── .gitkeep └── test/ ├── e2e/ │ ├── custom-assertions/ │ │ └── elementCount.js │ ├── nightwatch.conf.js │ ├── runner.js │ └── specs/ │ └── test.js └── unit/ ├── .eslintrc ├── jest.conf.js ├── setup.js └── specs/ └── HelloWorld.spec.js ================================================ FILE CONTENTS ================================================ ================================================ FILE: .babelrc ================================================ { "presets": [ ["env", { "modules": false, "targets": { "browsers": ["> 1%", "last 2 versions", "not ie <= 8"] } }], "stage-2" ], "plugins": ["transform-vue-jsx", "transform-runtime"], "env": { "test": { "presets": ["env", "stage-2"], "plugins": ["transform-vue-jsx", "transform-es2015-modules-commonjs", "dynamic-import-node"] } } } ================================================ FILE: .editorconfig ================================================ root = true [*] charset = utf-8 indent_style = space indent_size = 2 end_of_line = lf insert_final_newline = true trim_trailing_whitespace = true ================================================ FILE: .eslintignore ================================================ /build/ /config/ /dist/ /*.js /test/unit/coverage/ ================================================ FILE: .eslintrc.js ================================================ // https://eslint.org/docs/user-guide/configuring module.exports = { root: true, parserOptions: { parser: 'babel-eslint' }, env: { browser: true, }, extends: [ // https://github.com/vuejs/eslint-plugin-vue#priority-a-essential-error-prevention // consider switching to `plugin:vue/strongly-recommended` or `plugin:vue/recommended` for stricter rules. 'plugin:vue/essential', // https://github.com/standard/standard/blob/master/docs/RULES-en.md 'standard' ], // required to lint *.vue files plugins: [ 'vue' ], // add your custom rules here rules: { // allow async-await 'generator-star-spacing': 'off', // allow debugger during development 'no-debugger': process.env.NODE_ENV === 'production' ? 'error' : 'off' } } ================================================ FILE: .gitignore ================================================ .DS_Store node_modules/ /dist/ npm-debug.log* yarn-debug.log* yarn-error.log* /test/unit/coverage/ /test/e2e/reports/ selenium-debug.log # Editor directories and files .idea .vscode *.suo *.ntvs* *.njsproj *.sln ================================================ FILE: .postcssrc.js ================================================ // https://github.com/michael-ciniawsky/postcss-load-config module.exports = { "plugins": { "postcss-import": {}, "postcss-url": {}, // to edit target browsers: use "browserslist" field in package.json "autoprefixer": {} } } ================================================ FILE: README.md ================================================ # vue-task-node >vue-task-node 是一个基于Vue的任务节点图绘制插件(vue-task-node is a Vue based task node mapping plug-in) >在线Demo
[https://codesandbox.io/embed/5vvpyj792x?fontsize=14](https://codesandbox.io/embed/5vvpyj792x?fontsize=14) >如有问题欢迎邮箱✉:liwenbingmsc@qq.com ## 一、安装 ```js npm install vue-task-node -S ``` ## 二、引入 ```js import Vue from 'vue' import App from './App' import Vuex from 'vuex' import {TaskNode, TaskNodeStore} from 'vue-task-node' import 'vue-task-node/dist/css/vnode.css' Vue.config.productionTip = false Vue.use(TaskNode) Vue.use(Vuex) const store = new Vuex.Store({ modules: { TaskNodeStore } }) new Vue({ el: '#app', store, components: { App }, template: '' }) ``` ## 三、教程 起源:mml机器学习平台http://vidanao.com/ml/#/ > http://vidanao.com/ ## 四、版本 版本 | 说明 | 更新时间 |是否支持拖拽 | 是否支持节点连线 ---|---|---|---|--- 1.0.0 | 开端,根据数据绘制任务节点 | 2019年1月16日 | 否 | 否 1.0.1 | 修改代码规范Eslin | 2019年1月17日 | 否 | 否 1.0.2 | 调试入口文件 | 2019年1月17日 | 否 | 否 1.0.3 | npm下载包错误修改 | 2019年1月17日 | 否 | 否 1.0.4 | 添加鼠标右击后返回右击的node数据 | 2019年1月18日 | 否 | 否 1.0.x | 优化配置文件 | 2019年1月x日 | 否 | 否 1.1.0 | 代码结构调整,组件重新封装,样式使用less写 | 2019年2月28日 | 是 | 否 1.1.1 | 解决dist文件无法上传问题 | 2019年2月28日 | 是 | 否 1.1.2 | 解决dist文件无法上传问题 | 2019年2月28日 | 是 | 否 1.1.3 | 解决index.js找不到组件问题 | 2019年2月28日 | 是 | 否 1.1.4 | 解决index.js找不到组件问题 | 2019年2月28日 | 是 | 否 1.1.5 | 调整工作区样式问题 | 2019年3月1日 | 是 | 否 1.1.6 | 调整节点的事件传递 | 2019年3月1日 | 是 | 否 1.1.x | 优化样式,及配置文件 | 2019年3月x日 | 是 | 否 1.2.0 | 新增节点连线 | 2019年5月12日 | 是 | 是 1.2.1 | 新增路径鼠标事件 | 2019年5月23日 | 是 | 是 1.2.2 | 修改混入方式 | 2019年5月23日 | 是 | 是 1.3.0 | 工作区外拖拽节点到工作区内 | 2019年6月23日 | 是 | 是 1.3.3 | 添加全局参数设置 | 2019年6月28日 | 是 | 是 1.3.4 | 工作区缩放 | 2019年7月8日 | 是 | 是 1.3.5 | 新增ModelTree组件 | 2019年7月19日 | 是 | 是 1.3.6 | 调整1.3.5样式 | 2019年7月19日 | 是 | 是 1.3.7 | 节点拖拽出工作区问题,以及拖拽偏离问题 | 2019年7月23日 | 是 | 是 1.3.8 | 修复1.3.7bug | 2019年7月23日 | 是 | 是 1.3.9 | 修复计算工作区高宽bug | 2019年7月24日 | 是 | 是 1.4.0 | 修复ModeTree中的bug | 2019年7月24日 | 是 | 是 ## 五、开发环境 系统:`Windows 10`
屏幕分辨率:`1920*1080`
浏览器:
①谷歌极速浏览器 版本 `3.0.12.8` 浏览器缩放比例 `100%`
②谷歌浏览器 版本 `75.0.3770.142`(正式版本) (64 位) 浏览器缩放比例 `100%`
③`Microsoft Edge` 版本 `42.17134.1.0` 浏览器缩放比例 `100%`
## 六、出现路径错位问题分析 1. 目前兼容性还待解决,请使用谷歌浏览器浏览 2. 浏览器的缩放比例调整为100%,比例大或小都会是路径错位 3. `1.3.7`版本之前,节点拖拽连线,会被父级相对布局影响 4. 高分辨率问题,目前没有验证,我的1920*1080正常 ================================================ FILE: build/build.js ================================================ 'use strict' require('./check-versions')() process.env.NODE_ENV = 'production' const ora = require('ora') const rm = require('rimraf') const path = require('path') const chalk = require('chalk') const webpack = require('webpack') const config = require('../config') const webpackConfig = require('./webpack.prod.conf') const spinner = ora('building for production...') spinner.start() rm(path.join(config.build.assetsRoot, config.build.assetsSubDirectory), err => { if (err) throw err webpack(webpackConfig, (err, stats) => { spinner.stop() if (err) throw err process.stdout.write(stats.toString({ colors: true, modules: false, children: false, // If you are using ts-loader, setting this to true will make TypeScript errors show up during build. chunks: false, chunkModules: false }) + '\n\n') if (stats.hasErrors()) { console.log(chalk.red(' Build failed with errors.\n')) process.exit(1) } console.log(chalk.cyan(' Build complete.\n')) console.log(chalk.yellow( ' Tip: built files are meant to be served over an HTTP server.\n' + ' Opening index.html over file:// won\'t work.\n' )) }) }) ================================================ FILE: build/check-versions.js ================================================ 'use strict' const chalk = require('chalk') const semver = require('semver') const packageConfig = require('../package.json') const shell = require('shelljs') function exec (cmd) { return require('child_process').execSync(cmd).toString().trim() } const versionRequirements = [ { name: 'node', currentVersion: semver.clean(process.version), versionRequirement: packageConfig.engines.node } ] if (shell.which('npm')) { versionRequirements.push({ name: 'npm', currentVersion: exec('npm --version'), versionRequirement: packageConfig.engines.npm }) } module.exports = function () { const warnings = [] for (let i = 0; i < versionRequirements.length; i++) { const mod = versionRequirements[i] if (!semver.satisfies(mod.currentVersion, mod.versionRequirement)) { warnings.push(mod.name + ': ' + chalk.red(mod.currentVersion) + ' should be ' + chalk.green(mod.versionRequirement) ) } } if (warnings.length) { console.log('') console.log(chalk.yellow('To use this template, you must update following to modules:')) console.log() for (let i = 0; i < warnings.length; i++) { const warning = warnings[i] console.log(' ' + warning) } console.log() process.exit(1) } } ================================================ FILE: build/dist/css/vnode.css ================================================ *{-webkit-tap-highlight-color:rgba(0,0,0,0)}*,:after,:before{box-sizing:border-box}body{font-family:Helvetica Neue,Helvetica,PingFang SC,Hiragino Sans GB,Microsoft YaHei,\\5FAE\8F6F\96C5\9ED1,Arial,sans-serif;font-size:12px;line-height:1.5;color:#515a6e;background-color:#fff;-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale}article,aside,blockquote,body,button,dd,details,div,dl,dt,fieldset,figcaption,figure,footer,form,h1,h2,h3,h4,h5,h6,header,hgroup,hr,input,legend,li,menu,nav,ol,p,section,td,textarea,th,ul{margin:0;padding:0}button,input,select,textarea{font-family:inherit;font-size:inherit;line-height:inherit}input::-ms-clear,input::-ms-reveal{display:none}a{color:#2d8cf0;background:transparent;text-decoration:none;outline:none;cursor:pointer;transition:color .2s ease}a:hover{color:#57a3f3}a:active{color:#2b85e4}a:active,a:hover{outline:0;text-decoration:none}a[disabled]{color:#ccc;cursor:not-allowed;pointer-events:none}code,kbd,pre,samp{font-family:Consolas,Menlo,Courier,monospace}[class*=-icon-ok],[class*=-icon-run]{color:#2ecc71}[class*=-icon-wait]{color:#289de9}[class*=-icon-error]{color:#f15e5e}@font-face{font-family:Ionicons;src:url(/dist/fonts/ionicons.2ea87cd.ttf) format("truetype"),url(/dist/fonts/ionicons.e4536d4.woff) format("woff"),url(/dist/img/ionicons.9e11f71.svg#Ionicons) format("svg");font-weight:400;font-style:normal}[class*=" task-icon"],[class^=task-icon]{display:inline-block;font-family:Ionicons;speak:none;font-style:normal;font-weight:400;font-variant:normal;text-transform:none;text-rendering:auto;line-height:1;-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale;vertical-align:middle}.task-icon-58:before{content:"\E601"}.task-icon-9:before{content:"\E643"}.task-icon-57:before{content:"\E61F"}.task-icon-56:before{content:"\E671"}.task-icon-55:before{content:"\E745"}.task-icon-54:before{content:"\E661"}.task-icon-53:before{content:"\E6C3"}.task-icon-52:before{content:"\E660"}.task-icon-8:before{content:"\E670"}.task-icon-7:before{content:"\E693"}.task-icon-6:before{content:"\E646"}.task-icon-51:before{content:"\E6C4"}.task-icon-run:before{content:"\E614"}.task-icon-error:before{content:"\E67A"}.task-icon-48:before{content:"\E605"}.task-icon-47:before{content:"\E6C8"}.task-icon-46:before{content:"\E607"}.task-icon-45:before{content:"\E61A"}.task-icon-ok:before{content:"\E844"}.task-icon-wait:before{content:"\E6B5"}.task-icon-42:before{content:"\E664"}.task-icon-41:before{content:"\E6AB"}.task-icon-40:before{content:"\E6E5"}.task-icon-39:before{content:"\E600"}.task-icon-38:before{content:"\E61B"}.task-icon-37:before{content:"\E680"}.task-icon-36:before{content:"\E65F"}.task-icon-35:before{content:"\E642"}.task-icon-34:before{content:"\E75C"}.task-icon-30:before{content:"\E656"}.task-icon-5:before{content:"\E60D"}.task-icon-33:before{content:"\E60A"}.task-icon-32:before{content:"\E633"}.task-icon-31:before{content:"\E6C6"}.task-icon-29:before{content:"\EB64"}.task-icon-28:before{content:"\EB65"}.task-icon-27:before{content:"\EB66"}.task-icon-26:before{content:"\EB6A"}.task-icon-25:before{content:"\EB6B"}.task-icon-24:before{content:"\EBB8"}.task-icon-23:before{content:"\EBDA"}.task-icon-4:before{content:"\E602"}.task-icon-22:before{content:"\EC08"}.task-icon-21:before{content:"\EC13"}.task-icon-20:before{content:"\EC14"}.task-icon-19:before{content:"\EC20"}.task-icon-18:before{content:"\EC22"}.task-icon-17:before{content:"\EC23"}.task-icon-16:before{content:"\EC2A"}.task-icon-3:before{content:"\E603"}.task-icon-15:before{content:"\EC36"}.task-icon-14:before{content:"\EC37"}.task-icon-13:before{content:"\EC5B"}.task-icon-12:before{content:"\EC5C"}.task-icon-11:before{content:"\EC5D"}.task-icon-10:before{content:"\EC6A"}.task-icon-2:before{content:"\E61C"}.task-icon-1:before{content:"\E604"}.task-node body,.task-node foreignObject{background-color:transparent;overflow:visible}.task-node:hover{cursor:grab}.task-node-selected,.task-node:hover{background-color:rgba(227,244,255,.9)}.task-common-node{width:180px;height:30px;background-color:hsla(0,0%,100%,.9);border:1px solid #289de9;border-radius:15px;font-size:12px;transition:background-color .2s}.task-common-node-icon{float:left;color:#fff;font-size:16px;background-color:#289de9;width:26px;height:26px;margin:1px;border-radius:100%}.task-common-node-icon:before{float:left;margin:4px}.task-common-node-name{float:left;margin-left:2px;width:120px;height:28px;line-height:28px;font-size:14px;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.task-common-node-status{width:26px;height:26px;margin:1px;border-radius:100%;float:right;font-size:18px}.task-common-node-status:before{float:left;margin:4px}.task-common-node:hover{background-color:rgba(227,244,255,.9)}.task-in-common-ls{display:-ms-flexbox;display:flex;clear:both;margin-top:-34px;float:left;width:180px}.task-in-common-ls-wrap{height:1px;float:left;-ms-flex:1;flex:1}.task-out-common-ls{display:-ms-flexbox;display:flex;margin-top:-5px;clear:both;float:left;width:180px}.task-out-common-ls-wrap{height:1px;float:left;-ms-flex:1;flex:1}.task-initial-node{width:30px;height:30px;border:1px solid #ccc;border-radius:50%}.task-initial-node-in-wrap{clear:both;margin-top:-34px;float:left;width:30px}.task-initial-node-out-wrap{clear:both;margin-top:-5px;float:left;width:30px}.task-initial-node-name{float:left;width:30px;height:28px;line-height:28px;font-size:14px;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.task-initial-node-icon{float:left;color:#000;font-size:16px;width:26px;height:26px;margin:1px;border-radius:100%}.task-initial-node-icon:before{float:left;margin:4px}.task-initial-node:hover{background-color:rgba(227,244,255,.9)}.task-work-area{background-color:#fff;position:relative;overflow:auto}.task-work-area::-webkit-scrollbar{width:6px;height:6px}.task-work-area::-webkit-scrollbar-thumb{background-color:#aeaeae;min-height:50px;min-width:50px;border-radius:10px;transition:background-color .2s}.task-work-area::-webkit-scrollbar-track-piece{background-color:#eee}.task-port{width:10px;height:10px;float:right;margin-right:-5px;border:1px solid gray;border-radius:50%;background-color:#fff}.task-port-magnet{float:left;width:20px;height:20px;margin-top:-6px;margin-left:-6px;background-color:transparent;border-radius:50%}.task-port-in{cursor:default}.is-connected{width:0;height:0;border-style:solid;border-width:5px 4px 0;border-color:gray transparent transparent;background-color:transparent;border-radius:0;margin-top:6px}.task-port-out{cursor:crosshair}.task-tline{cursor:default}.task-tline-con{fill:none;stroke:hsla(0,0%,100%,0);stroke-width:15px}.task-tline-con-wrap{fill:none;stroke:gray;stroke-width:1px}.task-tline-dotted{stroke:rgba(57,202,116,.8);stroke-width:2px;stroke-dasharray:5;animation:ant-line 30s infinite linear}#app{font-family:Avenir,Helvetica,Arial,sans-serif;-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale;text-align:center;color:#2c3e50;padding:50px;background-color:#ccc} /*# sourceMappingURL=vnode.css.map */ ================================================ FILE: build/dist/vue-task-node.js ================================================ webpackJsonpvue_task_node([0],{"+E39":function(e,t,n){e.exports=!n("S82l")(function(){return 7!=Object.defineProperty({},"a",{get:function(){return 7}}).a})},"+ZMJ":function(e,t,n){var r=n("lOnJ");e.exports=function(e,t,n){if(r(e),void 0===t)return e;switch(n){case 1:return function(n){return e.call(t,n)};case 2:return function(n,r){return e.call(t,n,r)};case 3:return function(n,r,i){return e.call(t,n,r,i)}}return function(){return e.apply(t,arguments)}}},"3Eo+":function(e,t){var n=0,r=Math.random();e.exports=function(e){return"Symbol(".concat(void 0===e?"":e,")_",(++n+r).toString(36))}},"52gC":function(e,t){e.exports=function(e){if(void 0==e)throw TypeError("Can't call method on "+e);return e}},"7+uW":function(e,t,n){"use strict";(function(e){ /*! * Vue.js v2.6.7 * (c) 2014-2019 Evan You * Released under the MIT License. */ var n=Object.freeze({});function r(e){return void 0===e||null===e}function i(e){return void 0!==e&&null!==e}function o(e){return!0===e}function a(e){return"string"==typeof e||"number"==typeof e||"symbol"==typeof e||"boolean"==typeof e}function s(e){return null!==e&&"object"==typeof e}var c=Object.prototype.toString;function u(e){return"[object Object]"===c.call(e)}function l(e){return"[object RegExp]"===c.call(e)}function f(e){var t=parseFloat(String(e));return t>=0&&Math.floor(t)===t&&isFinite(e)}function p(e){return i(e)&&"function"==typeof e.then&&"function"==typeof e.catch}function d(e){return null==e?"":Array.isArray(e)||u(e)&&e.toString===c?JSON.stringify(e,null,2):String(e)}function v(e){var t=parseFloat(e);return isNaN(t)?e:t}function h(e,t){for(var n=Object.create(null),r=e.split(","),i=0;i-1)return e.splice(n,1)}}var _=Object.prototype.hasOwnProperty;function b(e,t){return _.call(e,t)}function $(e){var t=Object.create(null);return function(n){return t[n]||(t[n]=e(n))}}var x=/-(\w)/g,w=$(function(e){return e.replace(x,function(e,t){return t?t.toUpperCase():""})}),C=$(function(e){return e.charAt(0).toUpperCase()+e.slice(1)}),k=/\B([A-Z])/g,A=$(function(e){return e.replace(k,"-$1").toLowerCase()});var O=Function.prototype.bind?function(e,t){return e.bind(t)}:function(e,t){function n(n){var r=arguments.length;return r?r>1?e.apply(t,arguments):e.call(t,n):e.call(t)}return n._length=e.length,n};function S(e,t){t=t||0;for(var n=e.length-t,r=new Array(n);n--;)r[n]=e[n+t];return r}function T(e,t){for(var n in t)e[n]=t[n];return e}function j(e){for(var t={},n=0;n0,Y=Z&&Z.indexOf("edge/")>0,ee=(Z&&Z.indexOf("android"),Z&&/iphone|ipad|ipod|ios/.test(Z)||"ios"===G),te=(Z&&/chrome\/\d+/.test(Z),Z&&/phantomjs/.test(Z),Z&&Z.match(/firefox\/(\d+)/)),ne={}.watch,re=!1;if(q)try{var ie={};Object.defineProperty(ie,"passive",{get:function(){re=!0}}),window.addEventListener("test-passive",null,ie)}catch(e){}var oe=function(){return void 0===J&&(J=!q&&!W&&void 0!==e&&(e.process&&"server"===e.process.env.VUE_ENV)),J},ae=q&&window.__VUE_DEVTOOLS_GLOBAL_HOOK__;function se(e){return"function"==typeof e&&/native code/.test(e.toString())}var ce,ue="undefined"!=typeof Symbol&&se(Symbol)&&"undefined"!=typeof Reflect&&se(Reflect.ownKeys);ce="undefined"!=typeof Set&&se(Set)?Set:function(){function e(){this.set=Object.create(null)}return e.prototype.has=function(e){return!0===this.set[e]},e.prototype.add=function(e){this.set[e]=!0},e.prototype.clear=function(){this.set=Object.create(null)},e}();var le=E,fe=0,pe=function(){this.id=fe++,this.subs=[]};pe.prototype.addSub=function(e){this.subs.push(e)},pe.prototype.removeSub=function(e){g(this.subs,e)},pe.prototype.depend=function(){pe.target&&pe.target.addDep(this)},pe.prototype.notify=function(){var e=this.subs.slice();for(var t=0,n=e.length;t-1)if(o&&!b(i,"default"))a=!1;else if(""===a||a===A(e)){var c=He(String,i.type);(c<0||s0&&(ft((u=e(u,(n||"")+"_"+c))[0])&&ft(f)&&(s[l]=_e(f.text+u[0].text),u.shift()),s.push.apply(s,u)):a(u)?ft(f)?s[l]=_e(f.text+u):""!==u&&s.push(_e(u)):ft(u)&&ft(f)?s[l]=_e(f.text+u.text):(o(t._isVList)&&i(u.tag)&&r(u.key)&&i(n)&&(u.key="__vlist"+n+"_"+c+"__"),s.push(u)));return s}(e):void 0}function ft(e){return i(e)&&i(e.text)&&!1===e.isComment}function pt(e,t){if(e){for(var n=Object.create(null),r=ue?Reflect.ownKeys(e):Object.keys(e),i=0;idocument.createEvent("Event").timeStamp&&(fn=function(){return performance.now()});var dn=0,vn=function(e,t,n,r,i){this.vm=e,i&&(e._watcher=this),e._watchers.push(this),r?(this.deep=!!r.deep,this.user=!!r.user,this.lazy=!!r.lazy,this.sync=!!r.sync,this.before=r.before):this.deep=this.user=this.lazy=this.sync=!1,this.cb=n,this.id=++dn,this.active=!0,this.dirty=this.lazy,this.deps=[],this.newDeps=[],this.depIds=new ce,this.newDepIds=new ce,this.expression="","function"==typeof t?this.getter=t:(this.getter=function(e){if(!V.test(e)){var t=e.split(".");return function(e){for(var n=0;nun&&rn[n].id>e.id;)n--;rn.splice(n+1,0,e)}else rn.push(e);sn||(sn=!0,nt(pn))}}(this)},vn.prototype.run=function(){if(this.active){var e=this.get();if(e!==this.value||s(e)||this.deep){var t=this.value;if(this.value=e,this.user)try{this.cb.call(this.vm,e,t)}catch(e){ze(e,this.vm,'callback for watcher "'+this.expression+'"')}else this.cb.call(this.vm,e,t)}}},vn.prototype.evaluate=function(){this.value=this.get(),this.dirty=!1},vn.prototype.depend=function(){for(var e=this.deps.length;e--;)this.deps[e].depend()},vn.prototype.teardown=function(){if(this.active){this.vm._isBeingDestroyed||g(this.vm._watchers,this);for(var e=this.deps.length;e--;)this.deps[e].removeSub(this);this.active=!1}};var hn={enumerable:!0,configurable:!0,get:E,set:E};function mn(e,t,n){hn.get=function(){return this[t][n]},hn.set=function(e){this[t][n]=e},Object.defineProperty(e,n,hn)}function yn(e){e._watchers=[];var t=e.$options;t.props&&function(e,t){var n=e.$options.propsData||{},r=e._props={},i=e.$options._propKeys=[],o=!e.$parent;o||ke(!1);var a=function(o){i.push(o);var a=Re(o,t,n,e);Se(r,o,a),o in e||mn(e,"_props",o)};for(var s in t)a(s);ke(!0)}(e,t.props),t.methods&&function(e,t){e.$options.props;for(var n in t)e[n]="function"!=typeof t[n]?E:O(t[n],e)}(e,t.methods),t.data?function(e){var t=e.$options.data;u(t=e._data="function"==typeof t?function(e,t){ve();try{return e.call(t,t)}catch(e){return ze(e,t,"data()"),{}}finally{he()}}(t,e):t||{})||(t={});var n=Object.keys(t),r=e.$options.props,i=(e.$options.methods,n.length);for(;i--;){var o=n[i];0,r&&b(r,o)||H(o)||mn(e,"_data",o)}Oe(t,!0)}(e):Oe(e._data={},!0),t.computed&&function(e,t){var n=e._computedWatchers=Object.create(null),r=oe();for(var i in t){var o=t[i],a="function"==typeof o?o:o.get;0,r||(n[i]=new vn(e,a||E,E,gn)),i in e||_n(e,i,o)}}(e,t.computed),t.watch&&t.watch!==ne&&function(e,t){for(var n in t){var r=t[n];if(Array.isArray(r))for(var i=0;i-1:"string"==typeof e?e.split(",").indexOf(t)>-1:!!l(e)&&e.test(t)}function Tn(e,t){var n=e.cache,r=e.keys,i=e._vnode;for(var o in n){var a=n[o];if(a){var s=On(a.componentOptions);s&&!t(s)&&jn(n,o,r,i)}}}function jn(e,t,n,r){var i=e[t];!i||r&&i.tag===r.tag||i.componentInstance.$destroy(),e[t]=null,g(n,t)}!function(e){e.prototype._init=function(e){var t=this;t._uid=wn++,t._isVue=!0,e&&e._isComponent?function(e,t){var n=e.$options=Object.create(e.constructor.options),r=t._parentVnode;n.parent=t.parent,n._parentVnode=r;var i=r.componentOptions;n.propsData=i.propsData,n._parentListeners=i.listeners,n._renderChildren=i.children,n._componentTag=i.tag,t.render&&(n.render=t.render,n.staticRenderFns=t.staticRenderFns)}(t,e):t.$options=Pe(Cn(t.constructor),e||{},t),t._renderProxy=t,t._self=t,function(e){var t=e.$options,n=t.parent;if(n&&!t.abstract){for(;n.$options.abstract&&n.$parent;)n=n.$parent;n.$children.push(e)}e.$parent=n,e.$root=n?n.$root:e,e.$children=[],e.$refs={},e._watcher=null,e._inactive=null,e._directInactive=!1,e._isMounted=!1,e._isDestroyed=!1,e._isBeingDestroyed=!1}(t),function(e){e._events=Object.create(null),e._hasHookEvent=!1;var t=e.$options._parentListeners;t&&Xt(e,t)}(t),function(e){e._vnode=null,e._staticTrees=null;var t=e.$options,r=e.$vnode=t._parentVnode,i=r&&r.context;e.$slots=dt(t._renderChildren,i),e.$scopedSlots=n,e._c=function(t,n,r,i){return Ht(e,t,n,r,i,!1)},e.$createElement=function(t,n,r,i){return Ht(e,t,n,r,i,!0)};var o=r&&r.data;Se(e,"$attrs",o&&o.attrs||n,null,!0),Se(e,"$listeners",t._parentListeners||n,null,!0)}(t),nn(t,"beforeCreate"),function(e){var t=pt(e.$options.inject,e);t&&(ke(!1),Object.keys(t).forEach(function(n){Se(e,n,t[n])}),ke(!0))}(t),yn(t),function(e){var t=e.$options.provide;t&&(e._provided="function"==typeof t?t.call(e):t)}(t),nn(t,"created"),t.$options.el&&t.$mount(t.$options.el)}}(kn),function(e){var t={get:function(){return this._data}},n={get:function(){return this._props}};Object.defineProperty(e.prototype,"$data",t),Object.defineProperty(e.prototype,"$props",n),e.prototype.$set=Te,e.prototype.$delete=je,e.prototype.$watch=function(e,t,n){if(u(t))return xn(this,e,t,n);(n=n||{}).user=!0;var r=new vn(this,e,t,n);if(n.immediate)try{t.call(this,r.value)}catch(e){ze(e,this,'callback for immediate watcher "'+r.expression+'"')}return function(){r.teardown()}}}(kn),function(e){var t=/^hook:/;e.prototype.$on=function(e,n){var r=this;if(Array.isArray(e))for(var i=0,o=e.length;i1?S(n):n;for(var r=S(arguments,1),i='event handler for "'+e+'"',o=0,a=n.length;oparseInt(this.max)&&jn(a,s[0],s,this._vnode)),t.data.keepAlive=!0}return t||e&&e[0]}}};!function(e){var t={get:function(){return B}};Object.defineProperty(e,"config",t),e.util={warn:le,extend:T,mergeOptions:Pe,defineReactive:Se},e.set=Te,e.delete=je,e.nextTick=nt,e.observable=function(e){return Oe(e),e},e.options=Object.create(null),F.forEach(function(t){e.options[t+"s"]=Object.create(null)}),e.options._base=e,T(e.options.components,Mn),function(e){e.use=function(e){var t=this._installedPlugins||(this._installedPlugins=[]);if(t.indexOf(e)>-1)return this;var n=S(arguments,1);return n.unshift(this),"function"==typeof e.install?e.install.apply(e,n):"function"==typeof e&&e.apply(null,n),t.push(e),this}}(e),function(e){e.mixin=function(e){return this.options=Pe(this.options,e),this}}(e),An(e),function(e){F.forEach(function(t){e[t]=function(e,n){return n?("component"===t&&u(n)&&(n.name=n.name||e,n=this.options._base.extend(n)),"directive"===t&&"function"==typeof n&&(n={bind:n,update:n}),this.options[t+"s"][e]=n,n):this.options[t+"s"][e]}})}(e)}(kn),Object.defineProperty(kn.prototype,"$isServer",{get:oe}),Object.defineProperty(kn.prototype,"$ssrContext",{get:function(){return this.$vnode&&this.$vnode.ssrContext}}),Object.defineProperty(kn,"FunctionalRenderContext",{value:Nt}),kn.version="2.6.7";var Nn=h("style,class"),Dn=h("input,textarea,option,select,progress"),In=function(e,t,n){return"value"===n&&Dn(e)&&"button"!==t||"selected"===n&&"option"===e||"checked"===n&&"input"===e||"muted"===n&&"video"===e},Ln=h("contenteditable,draggable,spellcheck"),Pn=h("events,caret,typing,plaintext-only"),Fn=function(e,t){return zn(t)||"false"===t?"false":"contenteditable"===e&&Pn(t)?t:"true"},Rn=h("allowfullscreen,async,autofocus,autoplay,checked,compact,controls,declare,default,defaultchecked,defaultmuted,defaultselected,defer,disabled,enabled,formnovalidate,hidden,indeterminate,inert,ismap,itemscope,loop,multiple,muted,nohref,noresize,noshade,novalidate,nowrap,open,pauseonexit,readonly,required,reversed,scoped,seamless,selected,sortable,translate,truespeed,typemustmatch,visible"),Bn="http://www.w3.org/1999/xlink",Un=function(e){return":"===e.charAt(5)&&"xlink"===e.slice(0,5)},Hn=function(e){return Un(e)?e.slice(6,e.length):""},zn=function(e){return null==e||!1===e};function Vn(e){for(var t=e.data,n=e,r=e;i(r.componentInstance);)(r=r.componentInstance._vnode)&&r.data&&(t=Jn(r.data,t));for(;i(n=n.parent);)n&&n.data&&(t=Jn(t,n.data));return function(e,t){if(i(e)||i(t))return Kn(e,qn(t));return""}(t.staticClass,t.class)}function Jn(e,t){return{staticClass:Kn(e.staticClass,t.staticClass),class:i(e.class)?[e.class,t.class]:t.class}}function Kn(e,t){return e?t?e+" "+t:e:t||""}function qn(e){return Array.isArray(e)?function(e){for(var t,n="",r=0,o=e.length;r-1?gr(e,t,n):Rn(t)?zn(n)?e.removeAttribute(t):(n="allowfullscreen"===t&&"EMBED"===e.tagName?"true":t,e.setAttribute(t,n)):Ln(t)?e.setAttribute(t,Fn(t,n)):Un(t)?zn(n)?e.removeAttributeNS(Bn,Hn(t)):e.setAttributeNS(Bn,t,n):gr(e,t,n)}function gr(e,t,n){if(zn(n))e.removeAttribute(t);else{if(X&&!Q&&"TEXTAREA"===e.tagName&&"placeholder"===t&&""!==n&&!e.__ieph){var r=function(t){t.stopImmediatePropagation(),e.removeEventListener("input",r)};e.addEventListener("input",r),e.__ieph=!0}e.setAttribute(t,n)}}var _r={create:mr,update:mr};function br(e,t){var n=t.elm,o=t.data,a=e.data;if(!(r(o.staticClass)&&r(o.class)&&(r(a)||r(a.staticClass)&&r(a.class)))){var s=Vn(t),c=n._transitionClasses;i(c)&&(s=Kn(s,qn(c))),s!==n._prevClass&&(n.setAttribute("class",s),n._prevClass=s)}}var $r,xr,wr,Cr,kr,Ar,Or={create:br,update:br},Sr=/[\w).+\-_$\]]/;function Tr(e){var t,n,r,i,o,a=!1,s=!1,c=!1,u=!1,l=0,f=0,p=0,d=0;for(r=0;r=0&&" "===(h=e.charAt(v));v--);h&&Sr.test(h)||(u=!0)}}else void 0===i?(d=r+1,i=e.slice(0,r).trim()):m();function m(){(o||(o=[])).push(e.slice(d,r).trim()),d=r+1}if(void 0===i?i=e.slice(0,r).trim():0!==d&&m(),o)for(r=0;r-1?{exp:e.slice(0,Cr),key:'"'+e.slice(Cr+1)+'"'}:{exp:e,key:null};xr=e,Cr=kr=Ar=0;for(;!qr();)Wr(wr=Kr())?Zr(wr):91===wr&&Gr(wr);return{exp:e.slice(0,kr),key:e.slice(kr+1,Ar)}}(e);return null===n.key?e+"="+t:"$set("+n.exp+", "+n.key+", "+t+")"}function Kr(){return xr.charCodeAt(++Cr)}function qr(){return Cr>=$r}function Wr(e){return 34===e||39===e}function Gr(e){var t=1;for(kr=Cr;!qr();)if(Wr(e=Kr()))Zr(e);else if(91===e&&t++,93===e&&t--,0===t){Ar=Cr;break}}function Zr(e){for(var t=e;!qr()&&(e=Kr())!==t;);}var Xr,Qr="__r",Yr="__c";function ei(e,t,n){var r=Xr;return function i(){null!==t.apply(null,arguments)&&ri(e,i,n,r)}}var ti=We&&!(te&&Number(te[1])<=53);function ni(e,t,n,r){if(ti){var i=ln,o=t;t=o._wrapper=function(e){if(e.target===e.currentTarget||e.timeStamp>=i||0===e.timeStamp||e.target.ownerDocument!==document)return o.apply(this,arguments)}}Xr.addEventListener(e,t,re?{capture:n,passive:r}:n)}function ri(e,t,n,r){(r||Xr).removeEventListener(e,t._wrapper||t,n)}function ii(e,t){if(!r(e.data.on)||!r(t.data.on)){var n=t.data.on||{},o=e.data.on||{};Xr=t.elm,function(e){if(i(e[Qr])){var t=X?"change":"input";e[t]=[].concat(e[Qr],e[t]||[]),delete e[Qr]}i(e[Yr])&&(e.change=[].concat(e[Yr],e.change||[]),delete e[Yr])}(n),st(n,o,ni,ri,ei,t.context),Xr=void 0}}var oi,ai={create:ii,update:ii};function si(e,t){if(!r(e.data.domProps)||!r(t.data.domProps)){var n,o,a=t.elm,s=e.data.domProps||{},c=t.data.domProps||{};for(n in i(c.__ob__)&&(c=t.data.domProps=T({},c)),s)r(c[n])&&(a[n]="");for(n in c){if(o=c[n],"textContent"===n||"innerHTML"===n){if(t.children&&(t.children.length=0),o===s[n])continue;1===a.childNodes.length&&a.removeChild(a.childNodes[0])}if("value"===n&&"PROGRESS"!==a.tagName){a._value=o;var u=r(o)?"":String(o);ci(a,u)&&(a.value=u)}else if("innerHTML"===n&&Zn(a.tagName)&&r(a.innerHTML)){(oi=oi||document.createElement("div")).innerHTML=""+o+"";for(var l=oi.firstChild;a.firstChild;)a.removeChild(a.firstChild);for(;l.firstChild;)a.appendChild(l.firstChild)}else if(o!==s[n])try{a[n]=o}catch(e){}}}}function ci(e,t){return!e.composing&&("OPTION"===e.tagName||function(e,t){var n=!0;try{n=document.activeElement!==e}catch(e){}return n&&e.value!==t}(e,t)||function(e,t){var n=e.value,r=e._vModifiers;if(i(r)){if(r.number)return v(n)!==v(t);if(r.trim)return n.trim()!==t.trim()}return n!==t}(e,t))}var ui={create:si,update:si},li=$(function(e){var t={},n=/:(.+)/;return e.split(/;(?![^(]*\))/g).forEach(function(e){if(e){var r=e.split(n);r.length>1&&(t[r[0].trim()]=r[1].trim())}}),t});function fi(e){var t=pi(e.style);return e.staticStyle?T(e.staticStyle,t):t}function pi(e){return Array.isArray(e)?j(e):"string"==typeof e?li(e):e}var di,vi=/^--/,hi=/\s*!important$/,mi=function(e,t,n){if(vi.test(t))e.style.setProperty(t,n);else if(hi.test(n))e.style.setProperty(A(t),n.replace(hi,""),"important");else{var r=gi(t);if(Array.isArray(n))for(var i=0,o=n.length;i-1?t.split($i).forEach(function(t){return e.classList.add(t)}):e.classList.add(t);else{var n=" "+(e.getAttribute("class")||"")+" ";n.indexOf(" "+t+" ")<0&&e.setAttribute("class",(n+t).trim())}}function wi(e,t){if(t&&(t=t.trim()))if(e.classList)t.indexOf(" ")>-1?t.split($i).forEach(function(t){return e.classList.remove(t)}):e.classList.remove(t),e.classList.length||e.removeAttribute("class");else{for(var n=" "+(e.getAttribute("class")||"")+" ",r=" "+t+" ";n.indexOf(r)>=0;)n=n.replace(r," ");(n=n.trim())?e.setAttribute("class",n):e.removeAttribute("class")}}function Ci(e){if(e){if("object"==typeof e){var t={};return!1!==e.css&&T(t,ki(e.name||"v")),T(t,e),t}return"string"==typeof e?ki(e):void 0}}var ki=$(function(e){return{enterClass:e+"-enter",enterToClass:e+"-enter-to",enterActiveClass:e+"-enter-active",leaveClass:e+"-leave",leaveToClass:e+"-leave-to",leaveActiveClass:e+"-leave-active"}}),Ai=q&&!Q,Oi="transition",Si="animation",Ti="transition",ji="transitionend",Ei="animation",Mi="animationend";Ai&&(void 0===window.ontransitionend&&void 0!==window.onwebkittransitionend&&(Ti="WebkitTransition",ji="webkitTransitionEnd"),void 0===window.onanimationend&&void 0!==window.onwebkitanimationend&&(Ei="WebkitAnimation",Mi="webkitAnimationEnd"));var Ni=q?window.requestAnimationFrame?window.requestAnimationFrame.bind(window):setTimeout:function(e){return e()};function Di(e){Ni(function(){Ni(e)})}function Ii(e,t){var n=e._transitionClasses||(e._transitionClasses=[]);n.indexOf(t)<0&&(n.push(t),xi(e,t))}function Li(e,t){e._transitionClasses&&g(e._transitionClasses,t),wi(e,t)}function Pi(e,t,n){var r=Ri(e,t),i=r.type,o=r.timeout,a=r.propCount;if(!i)return n();var s=i===Oi?ji:Mi,c=0,u=function(){e.removeEventListener(s,l),n()},l=function(t){t.target===e&&++c>=a&&u()};setTimeout(function(){c0&&(n=Oi,l=a,f=o.length):t===Si?u>0&&(n=Si,l=u,f=c.length):f=(n=(l=Math.max(a,u))>0?a>u?Oi:Si:null)?n===Oi?o.length:c.length:0,{type:n,timeout:l,propCount:f,hasTransform:n===Oi&&Fi.test(r[Ti+"Property"])}}function Bi(e,t){for(;e.length1}function Ki(e,t){!0!==t.data.show&&Hi(t)}var qi=function(e){var t,n,s={},c=e.modules,u=e.nodeOps;for(t=0;tv?_(e,r(n[y+1])?null:n[y+1].elm,n,d,y,o):d>y&&$(0,t,p,v)}(p,h,y,n,l):i(y)?(i(e.text)&&u.setTextContent(p,""),_(p,null,y,0,y.length-1,n)):i(h)?$(0,h,0,h.length-1):i(e.text)&&u.setTextContent(p,""):e.text!==t.text&&u.setTextContent(p,t.text),i(v)&&i(d=v.hook)&&i(d=d.postpatch)&&d(e,t)}}}function k(e,t,n){if(o(n)&&i(e.parent))e.parent.data.pendingInsert=t;else for(var r=0;r-1,a.selected!==o&&(a.selected=o);else if(D(Qi(a),r))return void(e.selectedIndex!==s&&(e.selectedIndex=s));i||(e.selectedIndex=-1)}}function Xi(e,t){return t.every(function(t){return!D(t,e)})}function Qi(e){return"_value"in e?e._value:e.value}function Yi(e){e.target.composing=!0}function eo(e){e.target.composing&&(e.target.composing=!1,to(e.target,"input"))}function to(e,t){var n=document.createEvent("HTMLEvents");n.initEvent(t,!0,!0),e.dispatchEvent(n)}function no(e){return!e.componentInstance||e.data&&e.data.transition?e:no(e.componentInstance._vnode)}var ro={model:Wi,show:{bind:function(e,t,n){var r=t.value,i=(n=no(n)).data&&n.data.transition,o=e.__vOriginalDisplay="none"===e.style.display?"":e.style.display;r&&i?(n.data.show=!0,Hi(n,function(){e.style.display=o})):e.style.display=r?o:"none"},update:function(e,t,n){var r=t.value;!r!=!t.oldValue&&((n=no(n)).data&&n.data.transition?(n.data.show=!0,r?Hi(n,function(){e.style.display=e.__vOriginalDisplay}):zi(n,function(){e.style.display="none"})):e.style.display=r?e.__vOriginalDisplay:"none")},unbind:function(e,t,n,r,i){i||(e.style.display=e.__vOriginalDisplay)}}},io={name:String,appear:Boolean,css:Boolean,mode:String,type:String,enterClass:String,leaveClass:String,enterToClass:String,leaveToClass:String,enterActiveClass:String,leaveActiveClass:String,appearClass:String,appearActiveClass:String,appearToClass:String,duration:[Number,String,Object]};function oo(e){var t=e&&e.componentOptions;return t&&t.Ctor.options.abstract?oo(qt(t.children)):e}function ao(e){var t={},n=e.$options;for(var r in n.propsData)t[r]=e[r];var i=n._parentListeners;for(var o in i)t[w(o)]=i[o];return t}function so(e,t){if(/\d-keep-alive$/.test(t.tag))return e("keep-alive",{props:t.componentOptions.propsData})}var co=function(e){return e.tag||Kt(e)},uo=function(e){return"show"===e.name},lo={name:"transition",props:io,abstract:!0,render:function(e){var t=this,n=this.$slots.default;if(n&&(n=n.filter(co)).length){0;var r=this.mode;0;var i=n[0];if(function(e){for(;e=e.parent;)if(e.data.transition)return!0}(this.$vnode))return i;var o=oo(i);if(!o)return i;if(this._leaving)return so(e,i);var s="__transition-"+this._uid+"-";o.key=null==o.key?o.isComment?s+"comment":s+o.tag:a(o.key)?0===String(o.key).indexOf(s)?o.key:s+o.key:o.key;var c=(o.data||(o.data={})).transition=ao(this),u=this._vnode,l=oo(u);if(o.data.directives&&o.data.directives.some(uo)&&(o.data.show=!0),l&&l.data&&!function(e,t){return t.key===e.key&&t.tag===e.tag}(o,l)&&!Kt(l)&&(!l.componentInstance||!l.componentInstance._vnode.isComment)){var f=l.data.transition=T({},c);if("out-in"===r)return this._leaving=!0,ct(f,"afterLeave",function(){t._leaving=!1,t.$forceUpdate()}),so(e,i);if("in-out"===r){if(Kt(o))return u;var p,d=function(){p()};ct(c,"afterEnter",d),ct(c,"enterCancelled",d),ct(f,"delayLeave",function(e){p=e})}}return i}}},fo=T({tag:String,moveClass:String},io);function po(e){e.elm._moveCb&&e.elm._moveCb(),e.elm._enterCb&&e.elm._enterCb()}function vo(e){e.data.newPos=e.elm.getBoundingClientRect()}function ho(e){var t=e.data.pos,n=e.data.newPos,r=t.left-n.left,i=t.top-n.top;if(r||i){e.data.moved=!0;var o=e.elm.style;o.transform=o.WebkitTransform="translate("+r+"px,"+i+"px)",o.transitionDuration="0s"}}delete fo.mode;var mo={Transition:lo,TransitionGroup:{props:fo,beforeMount:function(){var e=this,t=this._update;this._update=function(n,r){var i=Yt(e);e.__patch__(e._vnode,e.kept,!1,!0),e._vnode=e.kept,i(),t.call(e,n,r)}},render:function(e){for(var t=this.tag||this.$vnode.data.tag||"span",n=Object.create(null),r=this.prevChildren=this.children,i=this.$slots.default||[],o=this.children=[],a=ao(this),s=0;s-1?Yn[e]=t.constructor===window.HTMLUnknownElement||t.constructor===window.HTMLElement:Yn[e]=/HTMLUnknownElement/.test(t.toString())},T(kn.options.directives,ro),T(kn.options.components,mo),kn.prototype.__patch__=q?qi:E,kn.prototype.$mount=function(e,t){return function(e,t,n){return e.$el=t,e.$options.render||(e.$options.render=ge),nn(e,"beforeMount"),new vn(e,function(){e._update(e._render(),n)},E,{before:function(){e._isMounted&&!e._isDestroyed&&nn(e,"beforeUpdate")}},!0),n=!1,null==e.$vnode&&(e._isMounted=!0,nn(e,"mounted")),e}(this,e=e&&q?tr(e):void 0,t)},q&&setTimeout(function(){B.devtools&&ae&&ae.emit("init",kn)},0);var yo=/\{\{((?:.|\r?\n)+?)\}\}/g,go=/[-.*+?^${}()|[\]\/\\]/g,_o=$(function(e){var t=e[0].replace(go,"\\$&"),n=e[1].replace(go,"\\$&");return new RegExp(t+"((?:.|\\n)+?)"+n,"g")});function bo(e,t){var n=t?_o(t):yo;if(n.test(e)){for(var r,i,o,a=[],s=[],c=n.lastIndex=0;r=n.exec(e);){(i=r.index)>c&&(s.push(o=e.slice(c,i)),a.push(JSON.stringify(o)));var u=Tr(r[1].trim());a.push("_s("+u+")"),s.push({"@binding":u}),c=i+r[0].length}return c\/=]+)(?:\s*(=)\s*(?:"([^"]*)"+|'([^']*)'+|([^\s"'=<>`]+)))?/,To=/^\s*((?:v-[\w-]+:|@|:|#)\[[^=]+\][^\s"'<>\/=]*)(?:\s*(=)\s*(?:"([^"]*)"+|'([^']*)'+|([^\s"'=<>`]+)))?/,jo="[a-zA-Z_][\\-\\.0-9_a-zA-Z"+U+"]*",Eo="((?:"+jo+"\\:)?"+jo+")",Mo=new RegExp("^<"+Eo),No=/^\s*(\/?)>/,Do=new RegExp("^<\\/"+Eo+"[^>]*>"),Io=/^]+>/i,Lo=/^",""":'"',"&":"&"," ":"\n"," ":"\t","'":"'"},Uo=/&(?:lt|gt|quot|amp|#39);/g,Ho=/&(?:lt|gt|quot|amp|#39|#10|#9);/g,zo=h("pre,textarea",!0),Vo=function(e,t){return e&&zo(e)&&"\n"===t[0]};function Jo(e,t){var n=t?Ho:Uo;return e.replace(n,function(e){return Bo[e]})}var Ko,qo,Wo,Go,Zo,Xo,Qo,Yo,ea=/^@|^v-on:/,ta=/^v-|^@|^:/,na=/([\s\S]*?)\s+(?:in|of)\s+([\s\S]*)/,ra=/,([^,\}\]]*)(?:,([^,\}\]]*))?$/,ia=/^\(|\)$/g,oa=/^\[.*\]$/,aa=/:(.*)$/,sa=/^:|^\.|^v-bind:/,ca=/\.[^.]+/g,ua=/^v-slot(:|$)|^#/,la=/[\r\n]/,fa=/\s+/g,pa=$(Co),da="_empty_";function va(e,t,n){return{type:1,tag:e,attrsList:t,attrsMap:function(e){for(var t={},n=0,r=e.length;n]*>)","i")),p=e.replace(f,function(e,n,r){return u=r.length,Fo(l)||"noscript"===l||(n=n.replace(//g,"$1").replace(//g,"$1")),Vo(l,n)&&(n=n.slice(1)),t.chars&&t.chars(n),""});c+=e.length-p.length,e=p,A(l,c-u,c)}else{var d=e.indexOf("<");if(0===d){if(Lo.test(e)){var v=e.indexOf("--\x3e");if(v>=0){t.shouldKeepComment&&t.comment(e.substring(4,v),c,c+v+3),w(v+3);continue}}if(Po.test(e)){var h=e.indexOf("]>");if(h>=0){w(h+2);continue}}var m=e.match(Io);if(m){w(m[0].length);continue}var y=e.match(Do);if(y){var g=c;w(y[0].length),A(y[1],g,c);continue}var _=C();if(_){k(_),Vo(_.tagName,e)&&w(1);continue}}var b=void 0,$=void 0,x=void 0;if(d>=0){for($=e.slice(d);!(Do.test($)||Mo.test($)||Lo.test($)||Po.test($)||(x=$.indexOf("<",1))<0);)d+=x,$=e.slice(d);b=e.substring(0,d)}d<0&&(b=e),b&&w(b.length),t.chars&&b&&t.chars(b,c-b.length,c)}if(e===n){t.chars&&t.chars(e);break}}function w(t){c+=t,e=e.substring(t)}function C(){var t=e.match(Mo);if(t){var n,r,i={tagName:t[1],attrs:[],start:c};for(w(t[0].length);!(n=e.match(No))&&(r=e.match(To)||e.match(So));)r.start=c,w(r[0].length),r.end=c,i.attrs.push(r);if(n)return i.unarySlash=n[1],w(n[0].length),i.end=c,i}}function k(e){var n=e.tagName,c=e.unarySlash;o&&("p"===r&&Oo(n)&&A(r),s(n)&&r===n&&A(n));for(var u=a(n)||!!c,l=e.attrs.length,f=new Array(l),p=0;p=0&&i[a].lowerCasedTag!==s;a--);else a=0;if(a>=0){for(var u=i.length-1;u>=a;u--)t.end&&t.end(i[u].tag,n,o);i.length=a,r=a&&i[a-1].tag}else"br"===s?t.start&&t.start(e,[],!0,n,o):"p"===s&&(t.start&&t.start(e,[],!1,n,o),t.end&&t.end(e,n,o))}A()}(e,{warn:Ko,expectHTML:t.expectHTML,isUnaryTag:t.isUnaryTag,canBeLeftOpenTag:t.canBeLeftOpenTag,shouldDecodeNewlines:t.shouldDecodeNewlines,shouldDecodeNewlinesForHref:t.shouldDecodeNewlinesForHref,shouldKeepComment:t.comments,outputSourceRange:t.outputSourceRange,start:function(e,n,a,s){var f=i&&i.ns||Yo(e);X&&"svg"===f&&(n=function(e){for(var t=[],n=0;n-1"+("true"===o?":("+t+")":":_q("+t+","+o+")")),Fr(e,"change","var $$a="+t+",$$el=$event.target,$$c=$$el.checked?("+o+"):("+a+");if(Array.isArray($$a)){var $$v="+(r?"_n("+i+")":i)+",$$i=_i($$a,$$v);if($$el.checked){$$i<0&&("+Jr(t,"$$a.concat([$$v])")+")}else{$$i>-1&&("+Jr(t,"$$a.slice(0,$$i).concat($$a.slice($$i+1))")+")}}else{"+Jr(t,"$$c")+"}",null,!0)}(e,r,i);else if("input"===o&&"radio"===a)!function(e,t,n){var r=n&&n.number,i=Br(e,"value")||"null";Nr(e,"checked","_q("+t+","+(i=r?"_n("+i+")":i)+")"),Fr(e,"change",Jr(t,i),null,!0)}(e,r,i);else if("input"===o||"textarea"===o)!function(e,t,n){var r=e.attrsMap.type,i=n||{},o=i.lazy,a=i.number,s=i.trim,c=!o&&"range"!==r,u=o?"change":"range"===r?Qr:"input",l="$event.target.value";s&&(l="$event.target.value.trim()"),a&&(l="_n("+l+")");var f=Jr(t,l);c&&(f="if($event.target.composing)return;"+f),Nr(e,"value","("+t+")"),Fr(e,u,f,null,!0),(s||a)&&Fr(e,"blur","$forceUpdate()")}(e,r,i);else if(!B.isReservedTag(o))return Vr(e,r,i),!1;return!0},text:function(e,t){t.value&&Nr(e,"textContent","_s("+t.value+")",t)},html:function(e,t){t.value&&Nr(e,"innerHTML","_s("+t.value+")",t)}},isPreTag:function(e){return"pre"===e},isUnaryTag:ko,mustUseProp:In,canBeLeftOpenTag:Ao,isReservedTag:Xn,getTagNamespace:Qn,staticKeys:function(e){return e.reduce(function(e,t){return e.concat(t.staticKeys||[])},[]).join(",")}(Ca)},Sa=$(function(e){return h("type,tag,attrsList,attrsMap,plain,parent,children,attrs,start,end,rawAttrsMap"+(e?","+e:""))});function Ta(e,t){e&&(ka=Sa(t.staticKeys||""),Aa=t.isReservedTag||M,function e(t){t.static=function(e){if(2===e.type)return!1;if(3===e.type)return!0;return!(!e.pre&&(e.hasBindings||e.if||e.for||m(e.tag)||!Aa(e.tag)||function(e){for(;e.parent;){if("template"!==(e=e.parent).tag)return!1;if(e.for)return!0}return!1}(e)||!Object.keys(e).every(ka)))}(t);if(1===t.type){if(!Aa(t.tag)&&"slot"!==t.tag&&null==t.attrsMap["inline-template"])return;for(var n=0,r=t.children.length;n|^function\s*\(/,Ea=/\([^)]*?\);*$/,Ma=/^[A-Za-z_$][\w$]*(?:\.[A-Za-z_$][\w$]*|\['[^']*?']|\["[^"]*?"]|\[\d+]|\[[A-Za-z_$][\w$]*])*$/,Na={esc:27,tab:9,enter:13,space:32,up:38,left:37,right:39,down:40,delete:[8,46]},Da={esc:["Esc","Escape"],tab:"Tab",enter:"Enter",space:[" ","Spacebar"],up:["Up","ArrowUp"],left:["Left","ArrowLeft"],right:["Right","ArrowRight"],down:["Down","ArrowDown"],delete:["Backspace","Delete","Del"]},Ia=function(e){return"if("+e+")return null;"},La={stop:"$event.stopPropagation();",prevent:"$event.preventDefault();",self:Ia("$event.target !== $event.currentTarget"),ctrl:Ia("!$event.ctrlKey"),shift:Ia("!$event.shiftKey"),alt:Ia("!$event.altKey"),meta:Ia("!$event.metaKey"),left:Ia("'button' in $event && $event.button !== 0"),middle:Ia("'button' in $event && $event.button !== 1"),right:Ia("'button' in $event && $event.button !== 2")};function Pa(e,t){var n=t?"nativeOn:":"on:",r="",i="";for(var o in e){var a=Fa(e[o]);e[o]&&e[o].dynamic?i+=o+","+a+",":r+='"'+o+'":'+a+","}return r="{"+r.slice(0,-1)+"}",i?n+"_d("+r+",["+i.slice(0,-1)+"])":n+r}function Fa(e){if(!e)return"function(){}";if(Array.isArray(e))return"["+e.map(function(e){return Fa(e)}).join(",")+"]";var t=Ma.test(e.value),n=ja.test(e.value),r=Ma.test(e.value.replace(Ea,""));if(e.modifiers){var i="",o="",a=[];for(var s in e.modifiers)if(La[s])o+=La[s],Na[s]&&a.push(s);else if("exact"===s){var c=e.modifiers;o+=Ia(["ctrl","shift","alt","meta"].filter(function(e){return!c[e]}).map(function(e){return"$event."+e+"Key"}).join("||"))}else a.push(s);return a.length&&(i+=function(e){return"if(!$event.type.indexOf('key')&&"+e.map(Ra).join("&&")+")return null;"}(a)),o&&(i+=o),"function($event){"+i+(t?"return "+e.value+"($event)":n?"return ("+e.value+")($event)":r?"return "+e.value:e.value)+"}"}return t||n?e.value:"function($event){"+(r?"return "+e.value:e.value)+"}"}function Ra(e){var t=parseInt(e,10);if(t)return"$event.keyCode!=="+t;var n=Na[e],r=Da[e];return"_k($event.keyCode,"+JSON.stringify(e)+","+JSON.stringify(n)+",$event.key,"+JSON.stringify(r)+")"}var Ba={on:function(e,t){e.wrapListeners=function(e){return"_g("+e+","+t.value+")"}},bind:function(e,t){e.wrapData=function(n){return"_b("+n+",'"+e.tag+"',"+t.value+","+(t.modifiers&&t.modifiers.prop?"true":"false")+(t.modifiers&&t.modifiers.sync?",true":"")+")"}},cloak:E},Ua=function(e){this.options=e,this.warn=e.warn||Er,this.transforms=Mr(e.modules,"transformCode"),this.dataGenFns=Mr(e.modules,"genData"),this.directives=T(T({},Ba),e.directives);var t=e.isReservedTag||M;this.maybeComponent=function(e){return!!e.component||!t(e.tag)},this.onceId=0,this.staticRenderFns=[],this.pre=!1};function Ha(e,t){var n=new Ua(t);return{render:"with(this){return "+(e?za(e,n):'_c("div")')+"}",staticRenderFns:n.staticRenderFns}}function za(e,t){if(e.parent&&(e.pre=e.pre||e.parent.pre),e.staticRoot&&!e.staticProcessed)return Va(e,t);if(e.once&&!e.onceProcessed)return Ja(e,t);if(e.for&&!e.forProcessed)return qa(e,t);if(e.if&&!e.ifProcessed)return Ka(e,t);if("template"!==e.tag||e.slotTarget||t.pre){if("slot"===e.tag)return function(e,t){var n=e.slotName||'"default"',r=Xa(e,t),i="_t("+n+(r?","+r:""),o=e.attrs||e.dynamicAttrs?es((e.attrs||[]).concat(e.dynamicAttrs||[]).map(function(e){return{name:w(e.name),value:e.value,dynamic:e.dynamic}})):null,a=e.attrsMap["v-bind"];!o&&!a||r||(i+=",null");o&&(i+=","+o);a&&(i+=(o?"":",null")+","+a);return i+")"}(e,t);var n;if(e.component)n=function(e,t,n){var r=t.inlineTemplate?null:Xa(t,n,!0);return"_c("+e+","+Wa(t,n)+(r?","+r:"")+")"}(e.component,e,t);else{var r;(!e.plain||e.pre&&t.maybeComponent(e))&&(r=Wa(e,t));var i=e.inlineTemplate?null:Xa(e,t,!0);n="_c('"+e.tag+"'"+(r?","+r:"")+(i?","+i:"")+")"}for(var o=0;o>>0}(a):"")+")"}(e,e.scopedSlots,t)+","),e.model&&(n+="model:{value:"+e.model.value+",callback:"+e.model.callback+",expression:"+e.model.expression+"},"),e.inlineTemplate){var o=function(e,t){var n=e.children[0];0;if(n&&1===n.type){var r=Ha(n,t.options);return"inlineTemplate:{render:function(){"+r.render+"},staticRenderFns:["+r.staticRenderFns.map(function(e){return"function(){"+e+"}"}).join(",")+"]}"}}(e,t);o&&(n+=o+",")}return n=n.replace(/,$/,"")+"}",e.dynamicAttrs&&(n="_b("+n+',"'+e.tag+'",'+es(e.dynamicAttrs)+")"),e.wrapData&&(n=e.wrapData(n)),e.wrapListeners&&(n=e.wrapListeners(n)),n}function Ga(e){return 1===e.type&&("slot"===e.tag||e.children.some(Ga))}function Za(e,t){var n=e.attrsMap["slot-scope"];if(e.if&&!e.ifProcessed&&!n)return Ka(e,t,Za,"null");if(e.for&&!e.forProcessed)return qa(e,t,Za);var r=e.slotScope===da?"":String(e.slotScope),i="function("+r+"){return "+("template"===e.tag?e.if&&n?"("+e.if+")?"+(Xa(e,t)||"undefined")+":undefined":Xa(e,t)||"undefined":za(e,t))+"}",o=r?"":",proxy:true";return"{key:"+(e.slotTarget||'"default"')+",fn:"+i+o+"}"}function Xa(e,t,n,r,i){var o=e.children;if(o.length){var a=o[0];if(1===o.length&&a.for&&"template"!==a.tag&&"slot"!==a.tag){var s=n?t.maybeComponent(a)?",1":",0":"";return""+(r||za)(a,t)+s}var c=n?function(e,t){for(var n=0,r=0;r':'
',os.innerHTML.indexOf(" ")>0}var us=!!q&&cs(!1),ls=!!q&&cs(!0),fs=$(function(e){var t=tr(e);return t&&t.innerHTML}),ps=kn.prototype.$mount;kn.prototype.$mount=function(e,t){if((e=e&&tr(e))===document.body||e===document.documentElement)return this;var n=this.$options;if(!n.render){var r=n.template;if(r)if("string"==typeof r)"#"===r.charAt(0)&&(r=fs(r));else{if(!r.nodeType)return this;r=r.innerHTML}else e&&(r=function(e){if(e.outerHTML)return e.outerHTML;var t=document.createElement("div");return t.appendChild(e.cloneNode(!0)),t.innerHTML}(e));if(r){0;var i=ss(r,{outputSourceRange:!1,shouldDecodeNewlines:us,shouldDecodeNewlinesForHref:ls,delimiters:n.delimiters,comments:n.comments},this),o=i.render,a=i.staticRenderFns;n.render=o,n.staticRenderFns=a}}return ps.call(this,e,t)},kn.compile=ss,t.a=kn}).call(t,n("DuR2"))},"77Pl":function(e,t,n){var r=n("EqjI");e.exports=function(e){if(!r(e))throw TypeError(e+" is not an object!");return e}},"7KvD":function(e,t){var n=e.exports="undefined"!=typeof window&&window.Math==Math?window:"undefined"!=typeof self&&self.Math==Math?self:Function("return this")();"number"==typeof __g&&(__g=n)},Cdx3:function(e,t,n){var r=n("sB3e"),i=n("lktj");n("uqUo")("keys",function(){return function(e){return i(r(e))}})},D2L2:function(e,t){var n={}.hasOwnProperty;e.exports=function(e,t){return n.call(e,t)}},DuR2:function(e,t){var n;n=function(){return this}();try{n=n||Function("return this")()||(0,eval)("this")}catch(e){"object"==typeof window&&(n=window)}e.exports=n},EqjI:function(e,t){e.exports=function(e){return"object"==typeof e?null!==e:"function"==typeof e}},FeBl:function(e,t){var n=e.exports={version:"2.6.5"};"number"==typeof __e&&(__e=n)},Ibhu:function(e,t,n){var r=n("D2L2"),i=n("TcQ7"),o=n("vFc/")(!1),a=n("ax3d")("IE_PROTO");e.exports=function(e,t){var n,s=i(e),c=0,u=[];for(n in s)n!=a&&r(s,n)&&u.push(n);for(;t.length>c;)r(s,n=t[c++])&&(~o(u,n)||u.push(n));return u}},MU5D:function(e,t,n){var r=n("R9M2");e.exports=Object("z").propertyIsEnumerable(0)?Object:function(e){return"String"==r(e)?e.split(""):Object(e)}},MmMw:function(e,t,n){var r=n("EqjI");e.exports=function(e,t){if(!r(e))return e;var n,i;if(t&&"function"==typeof(n=e.toString)&&!r(i=n.call(e)))return i;if("function"==typeof(n=e.valueOf)&&!r(i=n.call(e)))return i;if(!t&&"function"==typeof(n=e.toString)&&!r(i=n.call(e)))return i;throw TypeError("Can't convert object to primitive value")}},O4g8:function(e,t){e.exports=!0},ON07:function(e,t,n){var r=n("EqjI"),i=n("7KvD").document,o=r(i)&&r(i.createElement);e.exports=function(e){return o?i.createElement(e):{}}},QRG4:function(e,t,n){var r=n("UuGF"),i=Math.min;e.exports=function(e){return e>0?i(r(e),9007199254740991):0}},R9M2:function(e,t){var n={}.toString;e.exports=function(e){return n.call(e).slice(8,-1)}},S82l:function(e,t){e.exports=function(e){try{return!!e()}catch(e){return!0}}},SfB7:function(e,t,n){e.exports=!n("+E39")&&!n("S82l")(function(){return 7!=Object.defineProperty(n("ON07")("div"),"a",{get:function(){return 7}}).a})},TcQ7:function(e,t,n){var r=n("MU5D"),i=n("52gC");e.exports=function(e){return r(i(e))}},UuGF:function(e,t){var n=Math.ceil,r=Math.floor;e.exports=function(e){return isNaN(e=+e)?0:(e>0?r:n)(e)}},"VU/8":function(e,t){e.exports=function(e,t,n,r,i,o){var a,s=e=e||{},c=typeof e.default;"object"!==c&&"function"!==c||(a=e,s=e.default);var u,l="function"==typeof s?s.options:s;if(t&&(l.render=t.render,l.staticRenderFns=t.staticRenderFns,l._compiled=!0),n&&(l.functional=!0),i&&(l._scopeId=i),o?(u=function(e){(e=e||this.$vnode&&this.$vnode.ssrContext||this.parent&&this.parent.$vnode&&this.parent.$vnode.ssrContext)||"undefined"==typeof __VUE_SSR_CONTEXT__||(e=__VUE_SSR_CONTEXT__),r&&r.call(this,e),e&&e._registeredComponents&&e._registeredComponents.add(o)},l._ssrRegister=u):r&&(u=r),u){var f=l.functional,p=f?l.render:l.beforeCreate;f?(l._injectStyles=u,l.render=function(e,t){return u.call(t),p(e,t)}):l.beforeCreate=p?[].concat(p,u):[u]}return{esModule:a,exports:s,options:l}}},X8DO:function(e,t){e.exports=function(e,t){return{enumerable:!(1&e),configurable:!(2&e),writable:!(4&e),value:t}}},ax3d:function(e,t,n){var r=n("e8AB")("keys"),i=n("3Eo+");e.exports=function(e){return r[e]||(r[e]=i(e))}},e8AB:function(e,t,n){var r=n("FeBl"),i=n("7KvD"),o=i["__core-js_shared__"]||(i["__core-js_shared__"]={});(e.exports=function(e,t){return o[e]||(o[e]=void 0!==t?t:{})})("versions",[]).push({version:r.version,mode:n("O4g8")?"pure":"global",copyright:"© 2019 Denis Pushkarev (zloirock.ru)"})},evD5:function(e,t,n){var r=n("77Pl"),i=n("SfB7"),o=n("MmMw"),a=Object.defineProperty;t.f=n("+E39")?Object.defineProperty:function(e,t,n){if(r(e),t=o(t,!0),r(n),i)try{return a(e,t,n)}catch(e){}if("get"in n||"set"in n)throw TypeError("Accessors not supported!");return"value"in n&&(e[t]=n.value),e}},fZjL:function(e,t,n){e.exports={default:n("jFbC"),__esModule:!0}},fkB2:function(e,t,n){var r=n("UuGF"),i=Math.max,o=Math.min;e.exports=function(e,t){return(e=r(e))<0?i(e+t,0):o(e,t)}},hJx8:function(e,t,n){var r=n("evD5"),i=n("X8DO");e.exports=n("+E39")?function(e,t,n){return r.f(e,t,i(1,n))}:function(e,t,n){return e[t]=n,e}},jFbC:function(e,t,n){n("Cdx3"),e.exports=n("FeBl").Object.keys},kM2E:function(e,t,n){var r=n("7KvD"),i=n("FeBl"),o=n("+ZMJ"),a=n("hJx8"),s=n("D2L2"),c=function(e,t,n){var u,l,f,p=e&c.F,d=e&c.G,v=e&c.S,h=e&c.P,m=e&c.B,y=e&c.W,g=d?i:i[t]||(i[t]={}),_=g.prototype,b=d?r:v?r[t]:(r[t]||{}).prototype;for(u in d&&(n=t),n)(l=!p&&b&&void 0!==b[u])&&s(g,u)||(f=l?b[u]:n[u],g[u]=d&&"function"!=typeof b[u]?n[u]:m&&l?o(f,r):y&&b[u]==f?function(e){var t=function(t,n,r){if(this instanceof e){switch(arguments.length){case 0:return new e;case 1:return new e(t);case 2:return new e(t,n)}return new e(t,n,r)}return e.apply(this,arguments)};return t.prototype=e.prototype,t}(f):h&&"function"==typeof f?o(Function.call,f):f,h&&((g.virtual||(g.virtual={}))[u]=f,e&c.R&&_&&!_[u]&&a(_,u,f)))};c.F=1,c.G=2,c.S=4,c.P=8,c.B=16,c.W=32,c.U=64,c.R=128,e.exports=c},lOnJ:function(e,t){e.exports=function(e){if("function"!=typeof e)throw TypeError(e+" is not a function!");return e}},lktj:function(e,t,n){var r=n("Ibhu"),i=n("xnc9");e.exports=Object.keys||function(e){return r(e,i)}},mvHQ:function(e,t,n){e.exports={default:n("qkKv"),__esModule:!0}},qkKv:function(e,t,n){var r=n("FeBl"),i=r.JSON||(r.JSON={stringify:JSON.stringify});e.exports=function(e){return i.stringify.apply(i,arguments)}},sB3e:function(e,t,n){var r=n("52gC");e.exports=function(e){return Object(r(e))}},uqUo:function(e,t,n){var r=n("kM2E"),i=n("FeBl"),o=n("S82l");e.exports=function(e,t){var n=(i.Object||{})[e]||Object[e],a={};a[e]=t(n),r(r.S+r.F*o(function(){n(1)}),"Object",a)}},"vFc/":function(e,t,n){var r=n("TcQ7"),i=n("QRG4"),o=n("fkB2");e.exports=function(e){return function(t,n,a){var s,c=r(t),u=i(c.length),l=o(a,u);if(e&&n!=n){for(;u>l;)if((s=c[l++])!=s)return!0}else for(;u>l;l++)if((e||l in c)&&c[l]===n)return e||l||0;return!e&&-1}}},xnc9:function(e,t){e.exports="constructor,hasOwnProperty,isPrototypeOf,propertyIsEnumerable,toLocaleString,toString,valueOf".split(",")}}); //# sourceMappingURL=vue-task-node.js.map ================================================ FILE: build/utils.js ================================================ 'use strict' const path = require('path') const config = require('../config') const ExtractTextPlugin = require('extract-text-webpack-plugin') const packageConfig = require('../package.json') exports.assetsPath = function (_path) { const assetsSubDirectory = process.env.NODE_ENV === 'production' ? config.build.assetsSubDirectory : config.dev.assetsSubDirectory return path.posix.join(assetsSubDirectory, _path) } exports.cssLoaders = function (options) { options = options || {} const cssLoader = { loader: 'css-loader', options: { sourceMap: options.sourceMap } } const postcssLoader = { loader: 'postcss-loader', options: { sourceMap: options.sourceMap } } // generate loader string to be used with extract text plugin function generateLoaders (loader, loaderOptions) { const loaders = options.usePostCSS ? [cssLoader, postcssLoader] : [cssLoader] if (loader) { loaders.push({ loader: loader + '-loader', options: Object.assign({}, loaderOptions, { sourceMap: options.sourceMap }) }) } // Extract CSS when that option is specified // (which is the case during production build) if (options.extract) { return ExtractTextPlugin.extract({ use: loaders, fallback: 'vue-style-loader' }) } else { return ['vue-style-loader'].concat(loaders) } } // https://vue-loader.vuejs.org/en/configurations/extract-css.html return { css: generateLoaders(), postcss: generateLoaders(), less: generateLoaders('less'), sass: generateLoaders('sass', { indentedSyntax: true }), scss: generateLoaders('sass'), stylus: generateLoaders('stylus'), styl: generateLoaders('stylus') } } // Generate loaders for standalone style files (outside of .vue) exports.styleLoaders = function (options) { const output = [] const loaders = exports.cssLoaders(options) for (const extension in loaders) { const loader = loaders[extension] output.push({ test: new RegExp('\\.' + extension + '$'), use: loader }) } return output } exports.createNotifierCallback = () => { const notifier = require('node-notifier') return (severity, errors) => { if (severity !== 'error') return const error = errors[0] const filename = error.file && error.file.split('!').pop() notifier.notify({ title: packageConfig.name, message: severity + ': ' + error.name, subtitle: filename || '', icon: path.join(__dirname, 'logo.png') }) } } ================================================ FILE: build/vue-loader.conf.js ================================================ 'use strict' const utils = require('./utils') const config = require('../config') const isProduction = process.env.NODE_ENV === 'production' const sourceMapEnabled = isProduction ? config.build.productionSourceMap : config.dev.cssSourceMap module.exports = { loaders: utils.cssLoaders({ sourceMap: sourceMapEnabled, extract: isProduction }), cssSourceMap: sourceMapEnabled, cacheBusting: config.dev.cacheBusting, transformToRequire: { video: ['src', 'poster'], source: 'src', img: 'src', image: 'xlink:href' } } ================================================ FILE: build/webpack.base.conf.js ================================================ 'use strict' const path = require('path') const utils = require('./utils') const config = require('../config') const vueLoaderConfig = require('./vue-loader.conf') function resolve (dir) { return path.join(__dirname, '..', dir) } const createLintingRule = () => ({ test: /\.(js|vue)$/, loader: 'eslint-loader', enforce: 'pre', include: [resolve('src'), resolve('test')], options: { formatter: require('eslint-friendly-formatter'), emitWarning: !config.dev.showEslintErrorsInOverlay } }) module.exports = { context: path.resolve(__dirname, '../'), entry: { app: './src/main.js' }, output: { path: config.build.assetsRoot, filename: '[name].js', publicPath: process.env.NODE_ENV === 'production' ? config.build.assetsPublicPath : config.dev.assetsPublicPath }, resolve: { extensions: ['.js', '.vue', '.json'], alias: { 'vue$': 'vue/dist/vue.esm.js', '@': resolve('src'), } }, module: { rules: [ ...(config.dev.useEslint ? [createLintingRule()] : []), { test: /\.vue$/, loader: 'vue-loader', options: vueLoaderConfig }, { test: /\.js$/, loader: 'babel-loader', include: [resolve('src'), resolve('test'), resolve('node_modules/webpack-dev-server/client')] }, /* { test: /\.less$/, loader: "style-loader!css-loader!less-loader", },*/ { test: /\.(png|jpe?g|gif|svg)(\?.*)?$/, loader: 'url-loader', options: { limit: 10000, name: utils.assetsPath('img/[name].[hash:7].[ext]') } }, { test: /\.(mp4|webm|ogg|mp3|wav|flac|aac)(\?.*)?$/, loader: 'url-loader', options: { limit: 10000, name: utils.assetsPath('media/[name].[hash:7].[ext]') } }, { test: /\.(woff2?|eot|ttf|otf)(\?.*)?$/, loader: 'url-loader', options: { limit: 10000, name: utils.assetsPath('fonts/[name].[hash:7].[ext]') } } ] }, node: { // prevent webpack from injecting useless setImmediate polyfill because Vue // source contains it (although only uses it if it's native). setImmediate: false, // prevent webpack from injecting mocks to Node native modules // that does not make sense for the client dgram: 'empty', fs: 'empty', net: 'empty', tls: 'empty', child_process: 'empty' } } ================================================ FILE: build/webpack.dev.conf.js ================================================ 'use strict' const utils = require('./utils') const webpack = require('webpack') const config = require('../config') const merge = require('webpack-merge') const path = require('path') const baseWebpackConfig = require('./webpack.base.conf') const CopyWebpackPlugin = require('copy-webpack-plugin') const HtmlWebpackPlugin = require('html-webpack-plugin') const FriendlyErrorsPlugin = require('friendly-errors-webpack-plugin') const portfinder = require('portfinder') const HOST = process.env.HOST const PORT = process.env.PORT && Number(process.env.PORT) const devWebpackConfig = merge(baseWebpackConfig, { module: { rules: utils.styleLoaders({ sourceMap: config.dev.cssSourceMap, usePostCSS: true }) }, // cheap-module-eval-source-map is faster for development devtool: config.dev.devtool, // these devServer options should be customized in /config/index.js devServer: { clientLogLevel: 'warning', historyApiFallback: { rewrites: [ { from: /.*/, to: path.posix.join(config.dev.assetsPublicPath, 'index.html') }, ], }, hot: true, contentBase: false, // since we use CopyWebpackPlugin. compress: true, host: HOST || config.dev.host, port: PORT || config.dev.port, open: config.dev.autoOpenBrowser, overlay: config.dev.errorOverlay ? { warnings: false, errors: true } : false, publicPath: config.dev.assetsPublicPath, proxy: config.dev.proxyTable, quiet: true, // necessary for FriendlyErrorsPlugin watchOptions: { poll: config.dev.poll, } }, plugins: [ new webpack.DefinePlugin({ 'process.env': require('../config/dev.env') }), new webpack.HotModuleReplacementPlugin(), new webpack.NamedModulesPlugin(), // HMR shows correct file names in console on update. new webpack.NoEmitOnErrorsPlugin(), // https://github.com/ampedandwired/html-webpack-plugin new HtmlWebpackPlugin({ filename: 'index.html', template: 'index.html', inject: true }), // copy custom static assets new CopyWebpackPlugin([ { from: path.resolve(__dirname, '../static'), to: config.dev.assetsSubDirectory, ignore: ['.*'] } ]) ] }) module.exports = new Promise((resolve, reject) => { portfinder.basePort = process.env.PORT || config.dev.port portfinder.getPort((err, port) => { if (err) { reject(err) } else { // publish the new Port, necessary for e2e tests process.env.PORT = port // add port to devServer config devWebpackConfig.devServer.port = port // Add FriendlyErrorsPlugin devWebpackConfig.plugins.push(new FriendlyErrorsPlugin({ compilationSuccessInfo: { messages: [`Your application is running here: http://${devWebpackConfig.devServer.host}:${port}`], }, onErrors: config.dev.notifyOnErrors ? utils.createNotifierCallback() : undefined })) resolve(devWebpackConfig) } }) }) ================================================ FILE: build/webpack.prod.conf.js ================================================ 'use strict' const path = require('path') const utils = require('./utils') const webpack = require('webpack') const config = require('../config') const merge = require('webpack-merge') const baseWebpackConfig = require('./webpack.base.conf') const CopyWebpackPlugin = require('copy-webpack-plugin') const HtmlWebpackPlugin = require('html-webpack-plugin') const ExtractTextPlugin = require('extract-text-webpack-plugin') const OptimizeCSSPlugin = require('optimize-css-assets-webpack-plugin') const UglifyJsPlugin = require('uglifyjs-webpack-plugin') const env = process.env.NODE_ENV === 'testing' ? require('../config/test.env') : require('../config/prod.env') const webpackConfig = merge(baseWebpackConfig, { module: { rules: utils.styleLoaders({ sourceMap: config.build.productionSourceMap, extract: true, usePostCSS: true }) }, devtool: config.build.productionSourceMap ? config.build.devtool : false, output: { path: config.build.assetsRoot, // filename: utils.assetsPath('js/[name].[chunkhash].js'), // chunkFilename: utils.assetsPath('js/[id].[chunkhash].js') //path: path.resolve(__dirname, './dist'), publicPath: '/dist/', filename: 'vue-task-node.[name].js', // publicPath: process.env.NODE_ENV === 'production' // ? config.build.assetsPublicPath // : config.dev.assetsPublicPath library: 'vue-task-node', // library指定的就是你使用require时的模块名,这里便是require("PayKeyboard") libraryTarget: 'umd', //libraryTarget会生成不同umd的代码,可以只是commonjs标准的,也可以是指amd标准的,也可以只是通过script标签引入的。 }, plugins: [ // http://vuejs.github.io/vue-loader/en/workflow/production.html new webpack.DefinePlugin({ 'process.env': env }), new UglifyJsPlugin({ uglifyOptions: { compress: { warnings: false } }, sourceMap: config.build.productionSourceMap, parallel: true }), // extract css into its own file new ExtractTextPlugin({ filename: utils.assetsPath('css/[name].[contenthash].css'), // Setting the following option to `false` will not extract CSS from codesplit chunks. // Their CSS will instead be inserted dynamically with style-loader when the codesplit chunk has been loaded by webpack. // It's currently set to `true` because we are seeing that sourcemaps are included in the codesplit bundle as well when it's `false`, // increasing file size: https://github.com/vuejs-templates/webpack/issues/1110 allChunks: true, }), // Compress extracted CSS. We are using this plugin so that possible // duplicated CSS from different components can be deduped. new OptimizeCSSPlugin({ cssProcessorOptions: config.build.productionSourceMap ? { safe: true, map: { inline: false } } : { safe: true } }), // generate dist index.html with correct asset hash for caching. // you can customize output by editing /index.html // see https://github.com/ampedandwired/html-webpack-plugin new HtmlWebpackPlugin({ filename: process.env.NODE_ENV === 'testing' ? 'index.html' : config.build.index, template: 'index.html', inject: true, minify: { removeComments: true, collapseWhitespace: true, removeAttributeQuotes: true // more options: // https://github.com/kangax/html-minifier#options-quick-reference }, // necessary to consistently work with multiple chunks via CommonsChunkPlugin chunksSortMode: 'dependency' }), // keep module.id stable when vendor modules does not change new webpack.HashedModuleIdsPlugin(), // enable scope hoisting new webpack.optimize.ModuleConcatenationPlugin(), // split vendor js into its own file new webpack.optimize.CommonsChunkPlugin({ name: 'vendor', minChunks (module) { // any required modules inside node_modules are extracted to vendor return ( module.resource && /\.js$/.test(module.resource) && module.resource.indexOf( path.join(__dirname, '../node_modules') ) === 0 ) } }), // extract webpack runtime and module manifest to its own file in order to // prevent vendor hash from being updated whenever app bundle is updated new webpack.optimize.CommonsChunkPlugin({ name: 'manifest', minChunks: Infinity }), // This instance extracts shared chunks from code splitted chunks and bundles them // in a separate chunk, similar to the vendor chunk // see: https://webpack.js.org/plugins/commons-chunk-plugin/#extra-async-commons-chunk new webpack.optimize.CommonsChunkPlugin({ name: 'app', async: 'vendor-async', children: true, minChunks: 3 }), // copy custom static assets new CopyWebpackPlugin([ { from: path.resolve(__dirname, '../static'), to: config.build.assetsSubDirectory, ignore: ['.*'] } ]) ] }) if (config.build.productionGzip) { const CompressionWebpackPlugin = require('compression-webpack-plugin') webpackConfig.plugins.push( new CompressionWebpackPlugin({ asset: '[path].gz[query]', algorithm: 'gzip', test: new RegExp( '\\.(' + config.build.productionGzipExtensions.join('|') + ')$' ), threshold: 10240, minRatio: 0.8 }) ) } if (config.build.bundleAnalyzerReport) { const BundleAnalyzerPlugin = require('webpack-bundle-analyzer').BundleAnalyzerPlugin webpackConfig.plugins.push(new BundleAnalyzerPlugin()) } module.exports = webpackConfig ================================================ FILE: config/dev.env.js ================================================ 'use strict' const merge = require('webpack-merge') const prodEnv = require('./prod.env') module.exports = merge(prodEnv, { NODE_ENV: '"development"' }) ================================================ FILE: config/index.js ================================================ 'use strict' // Template version: 1.3.1 // see http://vuejs-templates.github.io/webpack for documentation. const path = require('path') module.exports = { dev: { // Paths assetsSubDirectory: 'static', assetsPublicPath: '/', proxyTable: {}, // Various Dev Server settings host: 'localhost', // can be overwritten by process.env.HOST port: 8080, // can be overwritten by process.env.PORT, if port is in use, a free one will be determined autoOpenBrowser: false, errorOverlay: true, notifyOnErrors: true, poll: false, // https://webpack.js.org/configuration/dev-server/#devserver-watchoptions- // Use Eslint Loader? // If true, your code will be linted during bundling and // linting errors and warnings will be shown in the console. useEslint: true, // If true, eslint errors and warnings will also be shown in the error overlay // in the browser. showEslintErrorsInOverlay: false, /** * Source Maps */ // https://webpack.js.org/configuration/devtool/#development devtool: 'cheap-module-eval-source-map', // If you have problems debugging vue-files in devtools, // set this to false - it *may* help // https://vue-loader.vuejs.org/en/options.html#cachebusting cacheBusting: true, cssSourceMap: true }, build: { // Template for index.html index: path.resolve(__dirname, '../dist/index.html'), // Paths assetsRoot: path.resolve(__dirname, '../dist'), assetsSubDirectory: '/', assetsPublicPath: './', /** * Source Maps */ productionSourceMap: true, // https://webpack.js.org/configuration/devtool/#production devtool: '#source-map', // Gzip off by default as many popular static hosts such as // Surge or Netlify already gzip all static assets for you. // Before setting to `true`, make sure to: // npm install --save-dev compression-webpack-plugin productionGzip: false, productionGzipExtensions: ['js', 'css'], // Run the build command with an extra argument to // View the bundle analyzer report after build finishes: // `npm run build --report` // Set to `true` or `false` to always turn it on or off bundleAnalyzerReport: process.env.npm_config_report } } ================================================ FILE: config/prod.env.js ================================================ 'use strict' module.exports = { NODE_ENV: '"production"' } ================================================ FILE: config/test.env.js ================================================ 'use strict' const merge = require('webpack-merge') const devEnv = require('./dev.env') module.exports = merge(devEnv, { NODE_ENV: '"testing"' }) ================================================ FILE: index.html ================================================ node
================================================ FILE: package.json ================================================ { "name": "vue-task-node", "version": "1.4.0", "description": "TaskNode Plugin! vue-task-node is a Vue based task node mapping plug-in", "author": "wenbing.li", "license": "MIT", "main": "src/lib/index.js", "private": false, "scripts": { "dev": "webpack-dev-server --inline --progress --config build/webpack.dev.conf.js", "start": "npm run dev", "lint": "eslint --ext .js,.vue src", "build": "node build/build.js" }, "files": [ "dist", "src" ], "dependencies": { "less": "^3.9.0", "less-loader": "^4.1.0", "vue": "^2.5.2", "vuex": "^3.1.1" }, "devDependencies": { "autoprefixer": "^7.1.2", "babel-core": "^6.22.1", "babel-eslint": "^8.2.1", "babel-helper-vue-jsx-merge-props": "^2.0.3", "babel-jest": "^21.0.2", "babel-loader": "^7.1.1", "babel-plugin-dynamic-import-node": "^1.2.0", "babel-plugin-syntax-jsx": "^6.18.0", "babel-plugin-transform-es2015-modules-commonjs": "^6.26.0", "babel-plugin-transform-runtime": "^6.22.0", "babel-plugin-transform-vue-jsx": "^3.5.0", "babel-preset-env": "^1.3.2", "babel-preset-stage-2": "^6.22.0", "babel-register": "^6.22.0", "chalk": "^2.0.1", "chromedriver": "^2.27.2", "copy-webpack-plugin": "^4.0.1", "cross-spawn": "^5.0.1", "css-loader": "^0.28.0", "eslint": "^4.15.0", "eslint-config-standard": "^10.2.1", "eslint-friendly-formatter": "^3.0.0", "eslint-loader": "^1.7.1", "eslint-plugin-import": "^2.7.0", "eslint-plugin-node": "^5.2.0", "eslint-plugin-promise": "^3.4.0", "eslint-plugin-standard": "^3.0.1", "eslint-plugin-vue": "^4.0.0", "extract-text-webpack-plugin": "^3.0.0", "file-loader": "^1.1.4", "friendly-errors-webpack-plugin": "^1.6.1", "html-webpack-plugin": "^2.30.1", "jest": "^22.0.4", "jest-serializer-vue": "^0.3.0", "jquery": "^1.12.4", "nightwatch": "^0.9.12", "node-notifier": "^5.1.2", "optimize-css-assets-webpack-plugin": "^3.2.0", "ora": "^1.2.0", "portfinder": "^1.0.13", "postcss-import": "^11.0.0", "postcss-loader": "^2.0.8", "postcss-url": "^7.2.1", "rimraf": "^2.6.0", "selenium-server": "^3.0.1", "semver": "^5.3.0", "shelljs": "^0.7.6", "uglifyjs-webpack-plugin": "^1.1.1", "url-loader": "^0.5.8", "vue-jest": "^1.0.2", "vue-loader": "^13.3.0", "vue-style-loader": "^3.0.1", "vue-template-compiler": "^2.5.2", "webpack": "^3.6.0", "webpack-bundle-analyzer": "^2.9.0", "webpack-dev-server": "^2.9.1", "webpack-merge": "^4.1.0" }, "engines": { "node": ">= 6.0.0", "npm": ">= 3.0.0" }, "browserslist": [ "> 1%", "last 2 versions", "not ie <= 8" ] } ================================================ FILE: src/App.vue ================================================ ================================================ FILE: src/lib/components/depend/ModelTree.vue ================================================ ================================================ FILE: src/lib/components/depend/TreeNode.vue ================================================ ================================================ FILE: src/lib/components/depend/index.js ================================================ import ModelTree from './ModelTree.vue' export default ModelTree ================================================ FILE: src/lib/components/node/README.md ================================================ ================================================ FILE: src/lib/components/node/common/common.vue ================================================ ================================================ FILE: src/lib/components/node/common/incommonls.vue ================================================ ================================================ FILE: src/lib/components/node/common/index.js ================================================ import Common from './common.vue' export default Common ================================================ FILE: src/lib/components/node/common/outcommonls.vue ================================================ ================================================ FILE: src/lib/components/node/index.js ================================================ import Node from './node.vue' export default Node ================================================ FILE: src/lib/components/node/initial/index.js ================================================ import Initial from './initial.vue' export default Initial ================================================ FILE: src/lib/components/node/initial/initial.vue ================================================ ================================================ FILE: src/lib/components/node/node.vue ================================================ ================================================ FILE: src/lib/components/nodemodel/index.js ================================================ import NodeModel from './nodemodel.vue' export default NodeModel ================================================ FILE: src/lib/components/nodemodel/nodemodel.vue ================================================ ================================================ FILE: src/lib/components/path/README.md ================================================ ``` node: { id: '', positionX: 0, positionY: 0, ... } ``` ================================================ FILE: src/lib/components/path/curvepath.vue ================================================ ================================================ FILE: src/lib/components/path/index.js ================================================ import Path from './tline.vue' import CurvePath from './curvepath.vue' export {Path, CurvePath} ================================================ FILE: src/lib/components/path/tline.vue ================================================ ================================================ FILE: src/lib/components/port/README.md ================================================ ``` node: { id: '', positionX: 0, positionY: 0, ... } ``` ================================================ FILE: src/lib/components/port/index.js ================================================ import InPort from './inport.vue' import OutPort from './outport.vue' export {InPort, OutPort} ================================================ FILE: src/lib/components/port/inport.vue ================================================ ================================================ FILE: src/lib/components/port/outport.vue ================================================ ================================================ FILE: src/lib/components/workarea/index.js ================================================ import WorkArea from './workarea.vue' export default WorkArea ================================================ FILE: src/lib/components/workarea/workarea.vue ================================================ ================================================ FILE: src/lib/index.js ================================================ 'use strict' import WorkArea from '../lib/components/workarea' import {InPort, OutPort} from '../lib/components/port' import {Path, CurvePath} from '../lib/components/path' import Node from '../lib/components/node' import Common from '../lib/components/node/common' import Initial from '../lib/components/node/initial' import NodeModel from '../lib/components/nodemodel' import ModelTree from '../lib/components/depend' import store from '../lib/store' import nodemix from '../lib/mixins/node' import './utils/firefoxCompatible.js' const views = { TaskWorkArea: WorkArea, TaskInPort: InPort, TaskOutPort: OutPort, TaskCommonNode: Common, TaskInitialNode: Initial, TaskNode: Node, TaskPath: Path, TaskCurvePath: CurvePath, TaskNodeModel: NodeModel, TaskModelTree: ModelTree } const install = function (Vue, opts = {}) { Object.keys(views).forEach(key => { Vue.component(key, views[key]) }) } export const TaskNode = install export const TaskNodeStore = store export const NodeMix = nodemix ================================================ FILE: src/lib/mixins/README.md ================================================ ``` node: { id: '', positionX: 0, positionY: 0, ... } ``` ================================================ FILE: src/lib/mixins/node.js ================================================ export default { props: { updateTem: Function }, methods: { updateTemp (val) { this.updateTem() }, selectNodeMethod: function (event, node, ref) { this.$emit('on-select', event, node, ref) }, dragStart: function (event, node) { this.$emit('on-drag-start', event, node) }, dragGing: function (event) { this.$emit('on-drag-ging', event) }, dragEnd: function (event, node) { this.$emit('on-drag-end', event, node) }, addPath: function (event, start, end) { this.$emit('on-add-path', event, start, end) }, mouseMenu: function (event, node) { this.$emit('on-mouse', event, node) } }, updated: function () { this.updateTem() } } ================================================ FILE: src/lib/mixins/tool.js ================================================ export default { methods: { isEmpty (obj) { if (obj) { return true } return false }, getContainersTop (el) { return el.offsetParent ? el.offsetTop + this.getContainersTop(el.offsetParent) : el.offsetTop }, getContainersLeft (el) { return el.offsetParent ? el.offsetLeft + this.getContainersLeft(el.offsetParent) : el.offsetLeft }, getBrowserHW () { // 获取浏览器可视高宽 if (window.innerHeight !== undefined) { return { 'width': window.innerWidth, 'height': window.innerHeight } } else if (document.compatMode === 'CSS1Compat') { return { 'width': document.documentElement.clientWidth, 'height': document.documentElement.clientHeight } } else { return { 'width': document.body.clientWidth, 'height': document.body.clientHeight } } }, transferCss (vl) { // 去除样式单位 let index = this.isCssInUnit(vl) let data = vl if (index >= 0) { data = vl.substring(0, index) } return data }, isCssInUnit (vl) { // 判断样式是否有单位 let units = ['%', 'px', 'in', 'cn', 'mm', 'em', 'ex', 'pt', 'pc'] let index = -1 for (const item of units) { if (vl.indexOf(item) >= 0) { index = vl.indexOf(item) break } } return index } } } ================================================ FILE: src/lib/store/index.js ================================================ const state = { vi_pathing_data: { isShow: false }, vi_config: { pathType: 'Q', dotted: false, scaling: {ZoomX: 1, ZoomY: 1} } } const getters = { getViPathingData () { return state.vi_pathing_data }, getViConfig () { return state.vi_config } } const mutations = { setMViPathingData (state, name) { state.vi_pathing_data = name }, setMViConfig (state, name) { state.vi_config = name } } const actions = { setViPathingData ({commit, state}, name) { commit('setMViPathingData', name) }, setViConfig ({commit, state}, name) { commit('setMViConfig', name) } } const store = { state, getters, mutations, actions } export default store ================================================ FILE: src/lib/styles/common/base.less ================================================ * { box-sizing: border-box; -webkit-tap-highlight-color: rgba(0, 0, 0, 0); } *:after, *::before { box-sizing: border-box; } body { font-family: @font-family; font-size: @font-size-small; line-height: @line-height-base; color: @text-color; background-color: @body-background; -webkit-font-smoothing: antialiased; -moz-osx-font-smoothing: grayscale; } body, div, dl, dt, dd, ul, ol, li, h1, h2, h3, h4, h5, h6, form, fieldset, legend, input, textarea, p, blockquote, th, td, hr, button, article, aside, details, figcaption, figure, footer, header, hgroup, menu, nav, section { margin: 0; padding: 0; } button, input, select, textarea { font-family: inherit; font-size: inherit; line-height: inherit; } input::-ms-clear, input::-ms-reveal { display: none; } a { color: @link-color; background: transparent; text-decoration: none; outline: none; cursor: pointer; transition: color @transition-time ease; &:hover { color: @link-hover-color; } &:active { color: @link-active-color; } &:active, &:hover { outline: 0; text-decoration: none; } &[disabled] { color: #ccc; cursor: @cursor-disabled; pointer-events: none; } } code, kbd, pre, samp { font-family: @code-family; } [class*="-icon-run"] { color: #2ecc71; } [class*="-icon-ok"] { color: #2ecc71; } [class*="-icon-wait"] { color: #289de9; } [class*="-icon-error"] { color: #f15e5e; } ================================================ FILE: src/lib/styles/common/iconfont/ionicons-font.less ================================================ @font-face { font-family: @ionicons-font-family; src: url("@{ionicons-font-path}/ionicons.ttf?v=@{ionicons-version}") format("truetype"), url("@{ionicons-font-path}/ionicons.woff?v=@{ionicons-version}") format("woff"), url("@{ionicons-font-path}/ionicons.svg?v=@{ionicons-version}#Ionicons") format("svg"); font-weight: normal; font-style: normal; } [class^="task-icon"], [class*=" task-icon"] { display: inline-block; font-family: @ionicons-font-family; speak: none; font-style: normal; font-weight: normal; font-variant: normal; text-transform: none; text-rendering: auto; line-height: 1; -webkit-font-smoothing: antialiased; -moz-osx-font-smoothing: grayscale; vertical-align: middle; } ================================================ FILE: src/lib/styles/common/iconfont/ionicons-icons.less ================================================ .task-icon-9:before { content: "\e643"; } .task-icon-57:before { content: "\e61f"; } .task-icon-56:before { content: "\e671"; } .task-icon-55:before { content: "\e745"; } .task-icon-54:before { content: "\e661"; } .task-icon-53:before { content: "\e6c3"; } .task-icon-52:before { content: "\e660"; } .task-icon-8:before { content: "\e670"; } .task-icon-7:before { content: "\e693"; } .task-icon-6:before { content: "\e646"; } .task-icon-51:before { content: "\e6c4"; } .task-icon-50:before { content: "\e614"; } .task-icon-49:before { content: "\e67a"; } .task-icon-48:before { content: "\e605"; } .task-icon-47:before { content: "\e6c8"; } .task-icon-46:before { content: "\e607"; } .task-icon-45:before { content: "\e61a"; } .task-icon-44:before { content: "\e844"; } .task-icon-43:before { content: "\e6b5"; } .task-icon-42:before { content: "\e664"; } .task-icon-61:before { content: "\e68d"; } .task-icon-60:before { content: "\e68e"; } .task-icon-41:before { content: "\e6ab"; } .task-icon-40:before { content: "\e6e5"; } .task-icon-39:before { content: "\e600"; } .task-icon-38:before { content: "\e61b"; } .task-icon-37:before { content: "\e680"; } .task-icon-36:before { content: "\e65f"; } .task-icon-35:before { content: "\e642"; } .task-icon-34:before { content: "\e75c"; } .task-icon-30:before { content: "\e656"; } .task-icon-5:before { content: "\e60d"; } .task-icon-33:before { content: "\e60a"; } .task-icon-32:before { content: "\e633"; } .task-icon-31:before { content: "\e6c6"; } .task-icon-29:before { content: "\eb64"; } .task-icon-28:before { content: "\eb65"; } .task-icon-27:before { content: "\eb66"; } .task-icon-26:before { content: "\eb6a"; } .task-icon-25:before { content: "\eb6b"; } .task-icon-24:before { content: "\ebb8"; } .task-icon-23:before { content: "\ebda"; } .task-icon-4:before { content: "\e602"; } .task-icon-22:before { content: "\ec08"; } .task-icon-21:before { content: "\ec13"; } .task-icon-20:before { content: "\ec14"; } .task-icon-19:before { content: "\ec20"; } .task-icon-18:before { content: "\ec22"; } .task-icon-17:before { content: "\ec23"; } .task-icon-16:before { content: "\ec2a"; } .task-icon-58:before { content: "\e606"; } .task-icon-3:before { content: "\e603"; } .task-icon-15:before { content: "\ec36"; } .task-icon-14:before { content: "\ec37"; } .task-icon-13:before { content: "\ec5b"; } .task-icon-12:before { content: "\ec5c"; } .task-icon-11:before { content: "\ec5d"; } .task-icon-10:before { content: "\ec6a"; } .task-icon-2:before { content: "\e61c"; } .task-icon-1:before { content: "\e604"; } .task-icon-59:before { content: "\ec6b"; } ================================================ FILE: src/lib/styles/common/iconfont/ionicons-variables.less ================================================ @ionicons-font-path: "./fonts"; @ionicons-font-family: "Ionicons"; @ionicons-version: "3.0.0"; @ionicons-prefix: task-icon-; ================================================ FILE: src/lib/styles/common/iconfont/ionicons.less ================================================ @import "ionicons-font"; @import "ionicons-icons"; @import "ionicons-variables"; ================================================ FILE: src/lib/styles/common/index.less ================================================ @import "./base"; @import "iconfont/ionicons"; ================================================ FILE: src/lib/styles/components/index.less ================================================ @import "./node/node"; @import "./node/common/index"; @import "./node/initial/initial"; @import "./workarea"; @import "./port"; @import "./tline"; @import "./nodemodel"; @import "./modeltree"; ================================================ FILE: src/lib/styles/components/modeltree.less ================================================ @modeltree-prefix-cls: ~"model-tree"; .@{modeltree-prefix-cls} { padding-left: 15px; &-node { cursor: -webkit-grab; cursor: grab; padding: 3px 10px; } & li{ list-style: none; } &-dir { cursor: pointer; padding: 5px 0; &:hover{ background-color: #f5f7fa; } } } ================================================ FILE: src/lib/styles/components/node/common/common.less ================================================ @common-prefix-cls: ~"@{css-prefix}common-node"; .@{common-prefix-cls} { width: 180px; height: 30px; background-color: hsla(0,0%,100%,.9); border: 1px solid #289de9; border-radius: 15px; font-size: 12px; -webkit-transition: background-color .2s; transition: background-color .2s; &-icon { float: left; color: #fff; font-size: 16px; background-color: #289de9; width: 26px; height: 26px; margin: 1px; border-radius: 100%; &:before{ float: left; margin: 4px; } } &-name { float: left; margin-left: 2px; width: 120px; height: 28px; line-height: 28px; font-size: 14px; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; } &-status { width: 26px; height: 26px; margin: 1px; border-radius: 100%; float: right; font-size: 18px; &:before{ float: left; margin: 4px; } } &:hover { background-color: @node-select-color ; } } ================================================ FILE: src/lib/styles/components/node/common/incommonls.less ================================================ @in-common-prefix-cls: ~"@{css-prefix}in-common-ls"; .@{in-common-prefix-cls} { display: flex; clear: both; margin-top: -34px; float: left; width: 180px; &-wrap { height: 1px; float: left; flex: 1; } } ================================================ FILE: src/lib/styles/components/node/common/index.less ================================================ @import "./common"; @import "./incommonls"; @import "./outcommonls"; ================================================ FILE: src/lib/styles/components/node/common/outcommonls.less ================================================ @out-common-prefix-cls: ~"@{css-prefix}out-common-ls"; .@{out-common-prefix-cls} { display: flex; margin-top: -5px; clear: both; float: left; width: 180px; &-wrap { height: 1px; float: left; flex: 1; } } ================================================ FILE: src/lib/styles/components/node/initial/initial.less ================================================ @initial-prefix-cls: ~"@{css-prefix}initial-node"; .@{initial-prefix-cls} { width: 30px; height: 30px; border: 1px solid #ccc; border-radius: 50%; &-in-wrap { clear: both; margin-top: -34px; float: left; width: 30px; } &-out-wrap { clear: both; margin-top: -5px; float: left; width: 30px; } &-name { float: left; width: 30px; height: 28px; line-height: 28px; font-size: 14px; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; } &-icon { float: left; color: #000; font-size: 16px; width: 26px; height: 26px; margin: 1px; border-radius: 100%; &:before{ float: left; margin: 4px; } } &:hover { background-color: @node-select-color ; } } ================================================ FILE: src/lib/styles/components/node/node.less ================================================ @node-prefix-cls: ~"@{css-prefix}node"; .@{node-prefix-cls} { .task-node-content{ position: absolute; top:0; left: 0; } & body{ background-color: transparent; overflow: visible; } & foreignObject { background-color: transparent; overflow: visible; } &:hover { cursor: grab; background-color:@node-select-color; } &-selected { background-color: @node-select-color; } } ================================================ FILE: src/lib/styles/components/nodemodel.less ================================================ @nodemodel-prefix-cls: ~"@{css-prefix}node-model"; .@{nodemodel-prefix-cls} { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; display: block; border: 1px solid transparent; cursor: -webkit-grab; &:hover { cursor: grab; background-color: #fff; border-color: #289de9; } &-label { height: 26px; line-height: 26px; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; } } ================================================ FILE: src/lib/styles/components/port.less ================================================ @port-prefix-cls: ~"@{css-prefix}port"; @inport-prefix-cls: ~"@{css-prefix}port-in"; @outport-prefix-cls: ~"@{css-prefix}port-out"; @inout-prefix-cls: ~"@{css-prefix}in-out"; .@{port-prefix-cls} { width: 10px; height: 10px; float: right; margin-right: -5px; border: 1px solid gray; border-radius: 50%; background-color: #fff; &-magnet { float: left; width: 20px; height: 20px; margin-top: -6px; margin-left: -6px; background-color: transparent; border-radius: 50%; } } .@{inport-prefix-cls} { cursor: default; &:hover { border: 1px solid #2d8cf0; width: 10px; height: 10px; box-shadow: 0px 0px 1px 3px #57a3f3; border-radius: 50%; margin-top: -1px; } } .@{inout-prefix-cls} { border: 1px solid #2d8cf0; width: 10px; height: 10px; box-shadow: 0px 0px 1px 3px #57a3f3; border-radius: 50%; margin-top: -1px; } .is-connected { width: 0; height: 0; border-style: solid; border-width: 5px 4px 0; border-color: gray transparent transparent; background-color: transparent; border-radius: 0; margin-top: 6px; } .@{outport-prefix-cls} { cursor: crosshair; } ================================================ FILE: src/lib/styles/components/tline.less ================================================ @tline-prefix-cls: ~"@{css-prefix}tline"; @hover-prefix-cls: ~"@{css-prefix}tline-hover"; .@{tline-prefix-cls} { cursor: default; &-con { fill: none; stroke: hsla(0,0%,100%,0); stroke-width: 15px; } &-con-wrap { fill: none; stroke: gray; stroke-width: 1px; } &-dotted{ stroke: rgba(57,202,116,.8); stroke-width: 2px; stroke-dasharray: 5; -webkit-animation: ant-line 30s infinite linear; animation: ant-line 30s infinite linear; } } .@{hover-prefix-cls} { fill: none; stroke: #aeaeae; stroke-width: 3px; } ================================================ FILE: src/lib/styles/components/workarea.less ================================================ @workarea-prefix-cls: ~"@{css-prefix}work-area"; .@{workarea-prefix-cls} { background-color: @body-background; position: relative; overflow: auto; cursor: -webkit-grab; &::-webkit-scrollbar { width: 6px; height: 6px; } &::-webkit-scrollbar-thumb { background-color: #aeaeae; min-height: 50px; min-width: 50px; -webkit-border-radius: 10px; border-radius: 10px; -webkit-transition: background-color .2s; -o-transition: background-color .2s; transition: background-color .2s; } &::-webkit-scrollbar-track-piece { background-color: #eee; } } ================================================ FILE: src/lib/styles/custom.less ================================================ // Prefix @css-prefix : task-; @css-prefix-icon : task-icon-; // Color @primary-color : #2d8cf0; @link-color : #2D8cF0; @link-hover-color : tint(@link-color, 20%); @link-active-color : shade(@link-color, 5%); @node-select-color :rgba(227,244,255,.9); @tooltip-color : #fff; // Base @body-background : #fff; @font-family : "Helvetica Neue",Helvetica,"PingFang SC","Hiragino Sans GB","Microsoft YaHei","微软雅黑",Arial,sans-serif; @code-family : Consolas,Menlo,Courier,monospace; @title-color : #17233d; @text-color : #515a6e; @font-size-base : 14px; @font-size-small : 12px; @font-size-large : 16px; @line-height-base : 1.5; @cursor-disabled : not-allowed; @border-radius-small : 4px; // Animation @animation-time : .3s; @transition-time : .2s; @ease-in-out : ease-in-out; // Background color @background-color-base : #f7f7f7; // base @tooltip-bg : rgba(70, 76, 91, .9); // Shadow @shadow-color : rgba(0, 0, 0, .2); @shadow-base : @shadow-down; @shadow-down : 0 1px 6px @shadow-color; // Z-index @zindex-tooltip : 1060; ================================================ FILE: src/lib/styles/index.less ================================================ @import "./common/index"; @import "./components/index"; @import "./custom"; ================================================ FILE: src/lib/utils/firefoxCompatible.js ================================================ import $ from 'jquery' import {browsers} from './tools.js' (window.___NODRAGEVENT = (browsers() === 'Firefox')) && $(document).on('dragover', function (e) { e = e.originalEvent window.__event = e.originalEvent window.___PAGEX = e.clientX || e.pageX window.___PAGEY = e.clientY || e.pageY }) ================================================ FILE: src/lib/utils/line.js ================================================ function XYObject (x, y) { this.x = x this.y = y } export default { /** * 计算二次贝塞尔曲线 Q线 * @param Mxy 起点坐标 * @param Txy 结束坐标 * @returns {string} 'M xy Q xy xy Txy' */ calculatedCurvePathQ (Mxy = {}, Txy = {}) { let mtx = (Txy.x - Mxy.x) / 4 let mty = (Txy.y - Mxy.y) / 4 if (mty < 0 && (mtx > 10 || mtx < -10)) { if (mty > -10 && mty < 10) { this.Q1xy = new XYObject(Mxy.x + 10, Mxy.y + 30) } else { this.Q1xy = new XYObject(Mxy.x + 10, Mxy.y + 4 * Math.abs(mty)) } this.Q2xy = new XYObject(Mxy.x + 2 * mtx, Mxy.y + 2 * mty) } else { this.Q1xy = new XYObject(Mxy.x, Mxy.y + 2 * mty) this.Q2xy = new XYObject(Mxy.x + 2 * mtx, Mxy.y + 2 * mty) } let path = 'M' + Mxy.x.toFixed(1) + ' ' + Mxy.y.toFixed(1) + ' Q ' + this.Q1xy.x.toFixed(1) + ' ' + this.Q1xy.y.toFixed(1) + ', ' + this.Q2xy.x.toFixed(1) + ' ' + this.Q2xy.y.toFixed(1) + ' T ' + Txy.x.toFixed(1) + ' ' + Txy.y.toFixed(1) return path }, /** * 计算折线 L线 * @param Mxy 起点坐标 * @param Txy 结束坐标 * @returns {string} 'M xy Q xy xy Txy' */ calculatedCurvePathL (Mxy = {}, Txy = {}) { let mtx = (Txy.x - Mxy.x) / 2 let mty = (Txy.y - Mxy.y) / 2 if (mty > 0) { this.L1xy = new XYObject(Mxy.x, Mxy.y + mty) this.L2xy = new XYObject(Txy.x, Mxy.y + mty) this.path = 'M' + Mxy.x.toFixed(1) + ' ' + Mxy.y.toFixed(1) + ' L ' + this.L1xy.x.toFixed(1) + ' ' + this.L1xy.y.toFixed(1) + ', ' + this.L2xy.x.toFixed(1) + ' ' + this.L2xy.y.toFixed(1) + ' T ' + Txy.x.toFixed(1) + ' ' + Txy.y.toFixed(1) } else { this.L1xy = new XYObject(Mxy.x, Mxy.y + 30) this.L2xy = new XYObject(Mxy.x + mtx, Mxy.y + 30) this.L3xy = new XYObject(Mxy.x + mtx, Txy.y - 30) this.L4xy = new XYObject(Txy.x, Txy.y - 30) this.path = 'M' + Mxy.x.toFixed(1) + ' ' + Mxy.y.toFixed(1) + ' L ' + this.L1xy.x.toFixed(1) + ' ' + this.L1xy.y.toFixed(1) + ', ' + this.L2xy.x.toFixed(1) + ' ' + this.L2xy.y.toFixed(1) + ', ' + this.L3xy.x.toFixed(1) + ' ' + this.L3xy.y.toFixed(1) + ', ' + this.L4xy.x.toFixed(1) + ' ' + this.L4xy.y.toFixed(1) + ' T ' + Txy.x.toFixed(1) + ' ' + Txy.y.toFixed(1) } return this.path }, /** * 计算直线 ML线 * @param Mxy 起点坐标 * @param Txy 结束坐标 * @returns {string} 'M xy Lxy' */ calculatedCurvePathML (Mxy = {}, Txy = {}) { this.path = 'M' + Mxy.x.toFixed(1) + ' ' + Mxy.y.toFixed(1) + ' L ' + Txy.x.toFixed(1) + ' ' + Txy.y.toFixed(1) return this.path }, /** * 获取曲线路径 * @param Mxy 起点坐标 * @param Txy 结束坐标 * @returns {string} 'M xy Q xy xy Txy' */ drawCurvePath (Mxy = {}, Txy = {}, type = 'Q', scaling) { let scalingMxy = { x: Mxy.x / scaling.ZoomX, y: Mxy.y / scaling.ZoomY } let scalingTxy = { x: Txy.x / scaling.ZoomX, y: Txy.y / scaling.ZoomY } if (type === 'Q') { return this.calculatedCurvePathQ(scalingMxy, scalingTxy) } else if (type === 'L') { return this.calculatedCurvePathL(scalingMxy, scalingTxy) } else if (type === 'ML') { return this.calculatedCurvePathML(scalingMxy, scalingTxy) } }, /** * 缩放坐标计算 * @param Mxy * @param Txy * @param scaling * @returns {{Mxy: {}, Txy: {}}} */ scalingCount (Mxy = {}, Txy = {}, scaling = {ZoomX: 1, ZoomY: 1}) { Mxy.x = Mxy.x * scaling.ZoomX Mxy.y = Mxy.y * scaling.ZoomY Txy.x = Txy.x * scaling.ZoomX Txy.y = Txy.y * scaling.ZoomY return {Mxy: Mxy, Txy: Txy} }, guid () { function S4 () { return (((1 + Math.random()) * 0x10000) | 0).toString(16).substring(1) } return (S4() + S4() + '-' + S4() + '-' + S4() + '-' + S4() + '-' + S4() + S4() + S4()) } } ================================================ FILE: src/lib/utils/tools.js ================================================ // 判断参数是否是其中之一 export function oneOf (value, validList) { for (let i = 0; i < validList.length; i++) { if (value === validList[i]) { return true } } return false } // 浏览器判断 export function browsers () { let userAgent = navigator.userAgent // 取得浏览器的userAgent字符串 if (userAgent.indexOf('Chrome') > -1) { if (userAgent.indexOf('Edge') > -1) { return 'Edge' } else { return 'Chrome' } } else if (userAgent.indexOf('Firefox') > -1) { return 'Firefox' } } // 判断缩放 export function zoomRatio () { let ratio = 0 let screen = window.screen let ua = navigator.userAgent.toLowerCase() if (window.devicePixelRatio !== undefined) { ratio = window.devicePixelRatio } else if (~ua.indexOf('msie')) { if (screen.deviceXDPI && screen.logicalXDPI) { ratio = screen.deviceXDPI / screen.logicalXDPI } } else if (window.outerWidth !== undefined && window.innerWidth !== undefined) { ratio = window.outerWidth / window.innerWidth } if (ratio) { ratio = Math.round(ratio * 100) } if (browsers() === 'Chrome') { return ratio } else { return 100 } } ================================================ FILE: src/main.js ================================================ import Vue from 'vue' import Vuex from 'vuex' import App from './App' import {TaskNode, TaskNodeStore} from './lib/index' import '../dist/css/vnode.css' // import '../src/lib/styles/index.less' Vue.config.productionTip = false Vue.use(TaskNode) Vue.use(Vuex) const store = new Vuex.Store({ modules: { TaskNodeStore } }) /* eslint-disable no-new */ new Vue({ el: '#app', store, components: { App }, template: '' }) ================================================ FILE: static/.gitkeep ================================================ ================================================ FILE: test/e2e/custom-assertions/elementCount.js ================================================ // A custom Nightwatch assertion. // The assertion name is the filename. // Example usage: // // browser.assert.elementCount(selector, count) // // For more information on custom assertions see: // http://nightwatchjs.org/guide#writing-custom-assertions exports.assertion = function (selector, count) { this.message = 'Testing if element <' + selector + '> has count: ' + count this.expected = count this.pass = function (val) { return val === this.expected } this.value = function (res) { return res.value } this.command = function (cb) { var self = this return this.api.execute(function (selector) { return document.querySelectorAll(selector).length }, [selector], function (res) { cb.call(self, res) }) } } ================================================ FILE: test/e2e/nightwatch.conf.js ================================================ require('babel-register') var config = require('../../config') // http://nightwatchjs.org/gettingstarted#settings-file module.exports = { src_folders: ['test/e2e/specs'], output_folder: 'test/e2e/reports', custom_assertions_path: ['test/e2e/custom-assertions'], selenium: { start_process: true, server_path: require('selenium-server').path, host: '127.0.0.1', port: 4444, cli_args: { 'webdriver.chrome.driver': require('chromedriver').path } }, test_settings: { default: { selenium_port: 4444, selenium_host: 'localhost', silent: true, globals: { devServerURL: 'http://localhost:' + (process.env.PORT || config.dev.port) } }, chrome: { desiredCapabilities: { browserName: 'chrome', javascriptEnabled: true, acceptSslCerts: true } }, firefox: { desiredCapabilities: { browserName: 'firefox', javascriptEnabled: true, acceptSslCerts: true } } } } ================================================ FILE: test/e2e/runner.js ================================================ // 1. start the dev server using production config process.env.NODE_ENV = 'testing' const webpack = require('webpack') const DevServer = require('webpack-dev-server') const webpackConfig = require('../../build/webpack.prod.conf') const devConfigPromise = require('../../build/webpack.dev.conf') let server devConfigPromise.then(devConfig => { const devServerOptions = devConfig.devServer const compiler = webpack(webpackConfig) server = new DevServer(compiler, devServerOptions) const port = devServerOptions.port const host = devServerOptions.host return server.listen(port, host) }) .then(() => { // 2. run the nightwatch test suite against it // to run in additional browsers: // 1. add an entry in test/e2e/nightwatch.conf.js under "test_settings" // 2. add it to the --env flag below // or override the environment flag, for example: `npm run e2e -- --env chrome,firefox` // For more information on Nightwatch's config file, see // http://nightwatchjs.org/guide#settings-file let opts = process.argv.slice(2) if (opts.indexOf('--config') === -1) { opts = opts.concat(['--config', 'test/e2e/nightwatch.conf.js']) } if (opts.indexOf('--env') === -1) { opts = opts.concat(['--env', 'chrome']) } const spawn = require('cross-spawn') const runner = spawn('./node_modules/.bin/nightwatch', opts, { stdio: 'inherit' }) runner.on('exit', function (code) { server.close() process.exit(code) }) runner.on('error', function (err) { server.close() throw err }) }) ================================================ FILE: test/e2e/specs/test.js ================================================ // For authoring Nightwatch tests, see // http://nightwatchjs.org/guide#usage module.exports = { 'default e2e tests': function (browser) { // automatically uses dev Server port from /config.index.js // default: http://localhost:8080 // see nightwatch.conf.js const devServer = browser.globals.devServerURL browser .url(devServer) .waitForElementVisible('#app', 5000) .assert.elementPresent('.hello') .assert.containsText('h1', 'Welcome to Your Vue.js App') .assert.elementCount('img', 1) .end() } } ================================================ FILE: test/unit/.eslintrc ================================================ { "env": { "jest": true }, "globals": { } } ================================================ FILE: test/unit/jest.conf.js ================================================ const path = require('path') module.exports = { rootDir: path.resolve(__dirname, '../../'), moduleFileExtensions: [ 'js', 'json', 'vue' ], moduleNameMapper: { '^@/(.*)$': '/src/$1' }, transform: { '^.+\\.js$': '/node_modules/babel-jest', '.*\\.(vue)$': '/node_modules/vue-jest' }, testPathIgnorePatterns: [ '/test/e2e' ], snapshotSerializers: ['/node_modules/jest-serializer-vue'], setupFiles: ['/test/unit/setup'], mapCoverage: true, coverageDirectory: '/test/unit/coverage', collectCoverageFrom: [ 'src/**/*.{js,vue}', '!src/main.js', '!**/node_modules/**' ] } ================================================ FILE: test/unit/setup.js ================================================ import Vue from 'vue' Vue.config.productionTip = false ================================================ FILE: test/unit/specs/HelloWorld.spec.js ================================================ import Vue from 'vue' import HelloWorld from '@/components/HelloWorld' describe('HelloWorld.vue', () => { it('should render correct contents', () => { const Constructor = Vue.extend(HelloWorld) const vm = new Constructor().$mount() expect(vm.$el.querySelector('.hello h1').textContent) .toEqual('Welcome to Your Vue.js App') }) })