├── demo ├── static │ ├── .gitkeep │ └── aa.png ├── build │ ├── logo.png │ ├── vue-loader.conf.js │ ├── build.js │ ├── check-versions.js │ ├── webpack.base.conf.js │ ├── utils.js │ ├── webpack.dev.conf.js │ └── webpack.prod.conf.js ├── src │ ├── assets │ │ └── logo.png │ ├── main.js │ ├── router │ │ └── index.js │ ├── App.vue │ └── components │ │ ├── no-scale.vue │ │ ├── link.vue │ │ └── app.vue ├── config │ ├── prod.env.js │ ├── dev.env.js │ └── index.js ├── .editorconfig ├── .gitignore ├── .babelrc ├── .postcssrc.js ├── index.html ├── README.md └── package.json ├── .npmignore ├── .gitignore ├── src ├── scene.js ├── link │ ├── index.js │ ├── link.js │ ├── curveLink.js │ ├── foldLink.js │ ├── arrowsFoldLink.js │ └── arrowsLink.js ├── container │ ├── index.js │ ├── oneItemContainer.js │ ├── ghomboidContainer.js │ ├── gridContainer.js │ └── container.js ├── node │ ├── index.js │ ├── ghomboidNode.js │ ├── tipNode.js │ ├── circleNode.js │ ├── heartNode.js │ ├── endPointNode.js │ ├── textNode.js │ ├── abstractNode.js │ ├── umlClassNode.js │ ├── tips.js │ └── node.js ├── index.js ├── util.js ├── element.js └── stage.js ├── .editorconfig ├── .babelrc ├── Readme.md ├── package.json └── yarn.lock /demo/static/.gitkeep: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /.npmignore: -------------------------------------------------------------------------------- 1 | demo/* 2 | node_modules/* 3 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | **/node_modules/** 2 | dist/* 3 | -------------------------------------------------------------------------------- /demo/static/aa.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/oo2o/jtopo/HEAD/demo/static/aa.png -------------------------------------------------------------------------------- /demo/build/logo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/oo2o/jtopo/HEAD/demo/build/logo.png -------------------------------------------------------------------------------- /demo/src/assets/logo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/oo2o/jtopo/HEAD/demo/src/assets/logo.png -------------------------------------------------------------------------------- /demo/config/prod.env.js: -------------------------------------------------------------------------------- 1 | 'use strict' 2 | module.exports = { 3 | NODE_ENV: '"production"' 4 | } 5 | -------------------------------------------------------------------------------- /src/scene.js: -------------------------------------------------------------------------------- 1 | export default class Scene { 2 | constructor(name){ 3 | this.name = name 4 | } 5 | 6 | 7 | } 8 | 9 | -------------------------------------------------------------------------------- /demo/config/dev.env.js: -------------------------------------------------------------------------------- 1 | 'use strict' 2 | const merge = require('webpack-merge') 3 | const prodEnv = require('./prod.env') 4 | 5 | module.exports = merge(prodEnv, { 6 | NODE_ENV: '"development"' 7 | }) 8 | -------------------------------------------------------------------------------- /demo/.editorconfig: -------------------------------------------------------------------------------- 1 | root = true 2 | 3 | [*] 4 | charset = utf-8 5 | indent_style = space 6 | indent_size = 2 7 | end_of_line = lf 8 | insert_final_newline = true 9 | trim_trailing_whitespace = true 10 | -------------------------------------------------------------------------------- /demo/.gitignore: -------------------------------------------------------------------------------- 1 | .DS_Store 2 | node_modules/ 3 | /dist/ 4 | npm-debug.log* 5 | yarn-debug.log* 6 | yarn-error.log* 7 | 8 | # Editor directories and files 9 | .idea 10 | .vscode 11 | *.suo 12 | *.ntvs* 13 | *.njsproj 14 | *.sln 15 | -------------------------------------------------------------------------------- /.editorconfig: -------------------------------------------------------------------------------- 1 | # editorconfig.org 2 | 3 | root = true 4 | 5 | [*] 6 | charset = utf-8 7 | end_of_line = lf 8 | indent_style = tab 9 | indent_size = 2 10 | trim_trailing_whitespace = true 11 | insert_final_newline = true 12 | 13 | [*.yml] 14 | indent_style = space 15 | -------------------------------------------------------------------------------- /src/link/index.js: -------------------------------------------------------------------------------- 1 | import Link from './link' 2 | import FoldLink from './foldLink' 3 | import CurverLink from './curveLink' 4 | import ArrowsLink from './arrowsLink' 5 | import ArrowsFoldLink from './arrowsFoldLink' 6 | 7 | export { Link, FoldLink, CurverLink, ArrowsLink, ArrowsFoldLink } 8 | -------------------------------------------------------------------------------- /.babelrc: -------------------------------------------------------------------------------- 1 | { 2 | "plugins": [ 3 | "transform-decorators-legacy", 4 | "transform-object-rest-spread", 5 | "transform-class-properties" 6 | ], 7 | "presets": [ 8 | ["env", { 9 | "debug": true, 10 | "targets": { 11 | "node": 6 12 | } 13 | } 14 | ] 15 | ] 16 | } 17 | -------------------------------------------------------------------------------- /src/container/index.js: -------------------------------------------------------------------------------- 1 | import Container from './container' 2 | import GhomboidContainer from './ghomboidContainer' 3 | import GridContainer from './gridContainer' 4 | import OneItemContainer from './oneItemContainer' 5 | 6 | export { Container, GhomboidContainer, GridContainer, OneItemContainer } 7 | -------------------------------------------------------------------------------- /demo/.babelrc: -------------------------------------------------------------------------------- 1 | { 2 | "presets": [ 3 | ["env", { 4 | "modules": false, 5 | "targets": { 6 | "browsers": ["> 1%", "last 2 versions", "not ie <= 8"] 7 | } 8 | }], 9 | "stage-2" 10 | ], 11 | "plugins": ["transform-vue-jsx", "transform-runtime"] 12 | } 13 | -------------------------------------------------------------------------------- /demo/.postcssrc.js: -------------------------------------------------------------------------------- 1 | // https://github.com/michael-ciniawsky/postcss-load-config 2 | 3 | module.exports = { 4 | "plugins": { 5 | "postcss-import": {}, 6 | "postcss-url": {}, 7 | // to edit target browsers: use "browserslist" field in package.json 8 | "autoprefixer": {} 9 | } 10 | } 11 | -------------------------------------------------------------------------------- /demo/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | Jtopo-Demo 7 | 8 | 9 |
10 | 11 | 12 | 13 | -------------------------------------------------------------------------------- /src/container/oneItemContainer.js: -------------------------------------------------------------------------------- 1 | import Container from './container' 2 | 3 | export default class GhomboidContainer extends Container { 4 | constructor() { 5 | super() 6 | this.rows = 1; 7 | this.cols = 1; 8 | this.cellWidth = 50; 9 | this.cellHeight = 50; 10 | 11 | this.setDragable(false); 12 | 13 | this.style.fillStyle = '0,100,100'; 14 | this.alpha = 0.5; 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /demo/src/main.js: -------------------------------------------------------------------------------- 1 | // The Vue build version to load with the `import` command 2 | // (runtime-only or standalone) has been set in webpack.base.conf with an alias. 3 | import Vue from 'vue' 4 | import App from './App' 5 | import router from './router' 6 | 7 | Vue.config.productionTip = false 8 | 9 | /* eslint-disable no-new */ 10 | new Vue({ 11 | el: '#app', 12 | router, 13 | components: { App }, 14 | template: '' 15 | }) 16 | -------------------------------------------------------------------------------- /src/node/index.js: -------------------------------------------------------------------------------- 1 | import CircleNode from './circleNode' 2 | import Node from './node' 3 | import EndPointNode from './endPointNode' 4 | import GhomboidNode from './ghomboidNode' 5 | import HeartNode from './heartNode' 6 | import TextNode from './textNode' 7 | import TipNode from './tipNode' 8 | import UMLClassNode from './umlClassNode' 9 | 10 | export { Node, CircleNode, EndPointNode, GhomboidNode, HeartNode, TextNode, TipNode, UMLClassNode } 11 | -------------------------------------------------------------------------------- /demo/README.md: -------------------------------------------------------------------------------- 1 | # y 2 | 3 | > A Vue.js project 4 | 5 | ## Build Setup 6 | 7 | ``` bash 8 | # install dependencies 9 | npm install 10 | 11 | # serve with hot reload at localhost:8080 12 | npm run dev 13 | 14 | # build for production with minification 15 | npm run build 16 | 17 | # build for production and view the bundle analyzer report 18 | npm run build --report 19 | ``` 20 | 21 | For a detailed explanation on how things work, check out the [guide](http://vuejs-templates.github.io/webpack/) and [docs for vue-loader](http://vuejs.github.io/vue-loader). 22 | -------------------------------------------------------------------------------- /Readme.md: -------------------------------------------------------------------------------- 1 | ### JTopo ES6版本 2 | 3 | #### 版本更新记录 4 | - 0.1.3 5 | 1. 修改对象初始化方法 6 | 1. 修复连接线报错问题 7 | 1. 修复提示框不显示问题 8 | 1. 修改Link对象 9 | - 0.1.2 10 | 1. 修改背景图片成可配置 11 | - 0.1.1 12 | 1. 修复在vue下鼠标事件出错问题 13 | 1. 修复节点提示框出错 14 | 1. 修复节点绑定鼠标事件出错 15 | 1. 美化节点形状 16 | - 0.1.0 初始化版本,从[JTopo](https://github.com/tuanjie54188/jtopo)copy代码并修改成在es6写法,支持导出功能 17 | #### 安装 18 | - npm install JTopo 19 | 20 | #### 实例 21 | - git clone https://github.com/oo2o/jtopo.git 22 | - cd jtopo/demo 23 | - yarn Or npm install 24 | - yarn run dev Or npm run dev 25 | 26 | ### API 27 | [JTopo](http://www.jtopo.com/) 相似 28 | > 后期整理 29 | ### 参考地址 30 | [JTopo](https://github.com/tuanjie54188/jtopo) 31 | -------------------------------------------------------------------------------- /demo/build/vue-loader.conf.js: -------------------------------------------------------------------------------- 1 | 'use strict' 2 | const utils = require('./utils') 3 | const config = require('../config') 4 | const isProduction = process.env.NODE_ENV === 'production' 5 | const sourceMapEnabled = isProduction 6 | ? config.build.productionSourceMap 7 | : config.dev.cssSourceMap 8 | 9 | module.exports = { 10 | loaders: utils.cssLoaders({ 11 | sourceMap: sourceMapEnabled, 12 | extract: isProduction 13 | }), 14 | cssSourceMap: sourceMapEnabled, 15 | cacheBusting: config.dev.cacheBusting, 16 | transformToRequire: { 17 | video: ['src', 'poster'], 18 | source: 'src', 19 | img: 'src', 20 | image: 'xlink:href' 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /demo/src/router/index.js: -------------------------------------------------------------------------------- 1 | import Vue from 'vue' 2 | import Router from 'vue-router' 3 | import App from '@/components/app' 4 | 5 | Vue.use(Router) 6 | 7 | export default new Router({ 8 | routes: [ 9 | { 10 | path: '/', 11 | name: 'index', 12 | title: '首页', 13 | component: App 14 | }, 15 | { 16 | path: '/link', 17 | name: 'link', 18 | title: '连接线', 19 | component: () => 20 | import ('@/components/link.vue'), 21 | }, 22 | { 23 | path: '/noscale', 24 | name: 'noscale', 25 | title: '选择框', 26 | component: () => 27 | import ('@/components/no-scale.vue'), 28 | } 29 | ] 30 | }) 31 | -------------------------------------------------------------------------------- /demo/src/App.vue: -------------------------------------------------------------------------------- 1 | 11 | 12 | 25 | 26 | 36 | -------------------------------------------------------------------------------- /src/node/ghomboidNode.js: -------------------------------------------------------------------------------- 1 | import Node from './node' 2 | 3 | export default class GhomboidNode extends Node { 4 | constructor(optiopn) { 5 | super(optiopn) 6 | this.offset = optiopn.offset || 10 7 | } 8 | 9 | draw(ctx) { 10 | ctx.save(); 11 | ctx.beginPath(); 12 | ctx.shadowBlur = 9; 13 | ctx.shadowColor = 'rgba(0,0,0,0.9)'; 14 | ctx.shadowOffsetX = 6; 15 | ctx.shadowOffsetY = 6; 16 | ctx.fillStyle = 'rgba(' + this.style.fillStyle + ',' + this.alpha + ')'; 17 | ctx.moveTo(this.x + this.offset, this.y); 18 | ctx.lineTo(this.x + this.offset + this.width, this.y); 19 | ctx.lineTo(this.x + this.width, this.y + this.height); 20 | ctx.lineTo(this.x, this.y + this.height); 21 | ctx.lineTo(this.x + this.offset, this.y); 22 | ctx.fill(); 23 | ctx.closePath(); 24 | ctx.restore(); 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /src/container/ghomboidContainer.js: -------------------------------------------------------------------------------- 1 | import Container from './container' 2 | 3 | export default class GhomboidContainer extends Container { 4 | constructor() { 5 | super() 6 | this.offset = 50 7 | } 8 | 9 | draw(ctx) { 10 | this.updateBound(); 11 | ctx.save(); 12 | ctx.beginPath(); 13 | ctx.shadowBlur = 9; 14 | ctx.shadowColor = 'rgba(0,0,0,0.9)'; 15 | ctx.shadowOffsetX = 6; 16 | ctx.shadowOffsetY = 6; 17 | ctx.fillStyle = 'rgba(' + this.style.fillStyle + ',' + this.alpha + ')'; 18 | ctx.moveTo(this.x + this.offset, this.y); 19 | ctx.lineTo(this.x + this.offset + this.width, this.y); 20 | ctx.lineTo(this.x + this.width, this.y + this.height); 21 | ctx.lineTo(this.x, this.y + this.height); 22 | ctx.lineTo(this.x + this.offset, this.y); 23 | ctx.fill(); 24 | ctx.stroke(); 25 | ctx.closePath(); 26 | ctx.restore(); 27 | } 28 | } 29 | -------------------------------------------------------------------------------- /src/link/link.js: -------------------------------------------------------------------------------- 1 | import Element from '../element' 2 | import { getDistance } from '../util' 3 | 4 | export default class Link extends Element { 5 | constructor(nodeA, nodeB, name) { 6 | super() 7 | this.nodeA = nodeA; 8 | this.nodeB = nodeB; 9 | this.name = name 10 | this.style = { strokeStyle: '116, 166, 250', alpha: 1, lineWidth: 2 }; 11 | } 12 | 13 | draw(ctx) { 14 | ctx.save(); 15 | ctx.beginPath(); 16 | ctx.strokeStyle = 'rgba(' + this.style.strokeStyle + ',' + this.style.alpha + ')'; 17 | ctx.lineWidth = this.style.lineWidth; 18 | ctx.moveTo(this.nodeA.x + this.nodeA.width / 2, this.nodeA.y + this.nodeA.height / 2); 19 | ctx.lineTo(this.nodeB.x + this.nodeB.width / 2, this.nodeB.y + this.nodeB.height / 2); 20 | ctx.stroke(); 21 | ctx.closePath(); 22 | ctx.restore(); 23 | } 24 | 25 | getLength() { 26 | return getDistance(this.nodeA, this.nodeB); 27 | } 28 | } 29 | -------------------------------------------------------------------------------- /src/node/tipNode.js: -------------------------------------------------------------------------------- 1 | import Node from './node' 2 | 3 | export default class TipNode extends Node { 4 | constructor(option) { 5 | super(option) 6 | this.width = option.width || 100 7 | this.height = option.height || 100 8 | } 9 | 10 | draw(ctx) { 11 | if (!this.visible) return; 12 | var x = this.x; 13 | var y = this.y; 14 | ctx.save(); 15 | ctx.beginPath(); 16 | ctx.strokeStyle = 'rgba(230, 230, 230, 0.8)'; 17 | ctx.moveTo(x + 50, y); 18 | ctx.quadraticCurveTo(x, y, x, y + 37.5); 19 | ctx.quadraticCurveTo(x, y + 75, x + 25, y + 75); 20 | ctx.quadraticCurveTo(x + 25, y + 95, x + 5, y + 100); 21 | ctx.quadraticCurveTo(x + 35, y + 95, x + 45, y + 75); 22 | ctx.quadraticCurveTo(x + 100, y + 75, x + 100, y + 37.5); 23 | ctx.quadraticCurveTo(x + 100, y, x + 50, y); 24 | 25 | ctx.strokeText(this.name, this.x + 20, this.y + 20); 26 | ctx.stroke(); 27 | ctx.closePath(); 28 | ctx.restore(); 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /src/link/curveLink.js: -------------------------------------------------------------------------------- 1 | import Link from './link' 2 | 3 | export default class CurveLink extends Link { 4 | constructor(nodeA, nodeB, name) { 5 | super(nodeA, nodeB) 6 | this.curve = '0.5' 7 | } 8 | 9 | draw(ctx) { 10 | let x1 = this.nodeA.x; 11 | let y1 = this.nodeA.y; 12 | let x2 = this.nodeB.x; 13 | let y2 = this.nodeB.y; 14 | let mx = x1; 15 | let my = y1; 16 | 17 | mx = x1 + (x2 - x1); 18 | my = y1 + (y2 - y1); 19 | 20 | mx *= this.curve; 21 | my *= this.curve; 22 | 23 | ctx.save(); 24 | ctx.beginPath(); 25 | ctx.strokeStyle = 'rgba(' + this.style.strokeStyle + ',' + this.style.alpha + ')'; 26 | ctx.lineWidth = this.style.lineWidth; 27 | ctx.moveTo(x1 + this.nodeA.width / 2, y1 + this.nodeA.height / 2); 28 | ctx.quadraticCurveTo(mx + this.nodeA.width / 2, my + this.nodeA.height / 2, 29 | x2 + this.nodeA.width / 2, y2 + this.nodeA.height / 2); 30 | ctx.stroke(); 31 | ctx.closePath(); 32 | ctx.restore(); 33 | } 34 | } 35 | -------------------------------------------------------------------------------- /src/node/circleNode.js: -------------------------------------------------------------------------------- 1 | import Node from './node' 2 | 3 | export default class CircleNode extends Node { 4 | constructor(option) { 5 | super(option) 6 | this.r = option.r|| 30 7 | this.beginDegree = option.beginDegree || 0 8 | let endDegree = option.endDegree || 2 9 | this.endDegree = endDegree * Math.PI 10 | } 11 | 12 | draw(ctx) { 13 | if (this.visible == false) return; 14 | ctx.save(); 15 | ctx.translate(this.x + this.width / 2, this.y + this.height / 2); 16 | ctx.rotate(this.rotate); 17 | ctx.scale(this.scala, this.scala); 18 | let w = this.r * 2 * this.scala; 19 | let h = this.r * 2 * this.scala; 20 | this.setWidth(w); 21 | this.setHeight(h); 22 | ctx.save(); 23 | ctx.beginPath(); 24 | ctx.fillStyle = 'rgba(' + this.style.fillStyle + ',' + this.alpha + ')'; 25 | ctx.arc(this.x + w / 2, this.y + h / 2, w / 2, this.beginDegree, this.endDegree, true); 26 | ctx.fill(); 27 | ctx.closePath(); 28 | ctx.restore(); 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /src/link/foldLink.js: -------------------------------------------------------------------------------- 1 | import Link from './link' 2 | 3 | export default class FoldLink extends Link { 4 | constructor(nodeA, nodeB, name) { 5 | super(nodeA, nodeB) 6 | this.fold = 'x' 7 | } 8 | 9 | draw(ctx) { 10 | let x1 = this.nodeA.x; 11 | let y1 = this.nodeA.y; 12 | let x2 = this.nodeB.x; 13 | let y2 = this.nodeB.y; 14 | let mx = x1; 15 | let my = y1; 16 | 17 | if (x1 == x2 || y1 == y2) { 18 | super.draw(ctx) 19 | } else { 20 | if (this.fold == 'x') { 21 | mx = x1 + (x2 - x1); 22 | } else { 23 | my = y1 + (y2 - y1); 24 | } 25 | ctx.save(); 26 | ctx.beginPath(); 27 | ctx.strokeStyle = 'rgba(' + this.style.strokeStyle + ',' + this.style.alpha + ')'; 28 | ctx.lineWidth = this.style.lineWidth; 29 | ctx.moveTo(x1 + this.nodeA.width / 2, y1 + this.nodeA.height / 2); 30 | ctx.lineTo(mx + this.nodeA.width / 2, my + this.nodeA.height / 2); 31 | ctx.lineTo(x2 + this.nodeA.width / 2, y2 + this.nodeA.height / 2); 32 | ctx.stroke(); 33 | ctx.closePath(); 34 | ctx.restore(); 35 | } 36 | } 37 | } 38 | -------------------------------------------------------------------------------- /src/index.js: -------------------------------------------------------------------------------- 1 | import { Node, CircleNode, EndPointNode, GhomboidNode, HeartNode, TextNode, TipNode, UMLClassNode } from './node' 2 | import Stage from './stage' 3 | import Scene from './scene' 4 | import { Link, FoldLink, CurverLink, ArrowsLink, ArrowsFoldLink } from './link' 5 | import { Container, GhomboidContainer, GridContainer, OneItemContainer } from './container' 6 | 7 | const JTopo = { 8 | constructor(name){ 9 | this.name = name 10 | }, 11 | Node: Node, 12 | CircleNode: CircleNode, 13 | EndPointNode: EndPointNode, 14 | GhomboidNode: GhomboidNode, 15 | HeartNode: HeartNode, 16 | TextNode: TextNode, 17 | TipNode: TipNode, 18 | UMLClassNode: UMLClassNode, 19 | Stage: Stage, 20 | Scene: Scene, 21 | Link: Link, 22 | FoldLink: FoldLink, 23 | CurverLink: CurverLink, 24 | ArrowsLink: ArrowsLink, 25 | ArrowsFoldLink: ArrowsFoldLink, 26 | Container: Container, 27 | GhomboidContainer: GhomboidContainer, 28 | GridContainer: GridContainer, 29 | OneItemContainer: OneItemContainer, 30 | Version: '0.1.0', 31 | description: '参考与https://github.com/tuanjie54188/jtopo' 32 | } 33 | 34 | export default JTopo 35 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "jtopo", 3 | "version": "0.1.3", 4 | "description": "canvas operate", 5 | "main": "dist/index.js", 6 | "scripts": { 7 | "rimraf": "./node_modules/.bin/rimraf ./dist", 8 | "prepublish": "./node_modules/.bin/babel src --out-dir dist", 9 | "dev": "cd demo && npm run dev", 10 | "link-all": "npm link", 11 | "upgrade": "npm publish" 12 | }, 13 | "repository": { 14 | "type": "git", 15 | "url": "git+https://github.com/oo2o/jtopo.git" 16 | }, 17 | "keywords": [ 18 | "jtopo" 19 | ], 20 | "author": "oo2o", 21 | "license": "ISC", 22 | "bugs": { 23 | "url": "https://github.com/oo2o/jtopo/issues" 24 | }, 25 | "homepage": "https://github.com/oo2o/jtopo#readme", 26 | "dependencies": { 27 | "babel": "^6.23.0", 28 | "babel-cli": "^6.24.1", 29 | "babel-core": "^6.25.0", 30 | "babel-plugin-transform-class-properties": "^6.24.1", 31 | "babel-plugin-transform-decorators-legacy": "^1.3.4", 32 | "babel-plugin-transform-object-rest-spread": "^6.23.0", 33 | "babel-preset-env": "^1.5.2", 34 | "cross-env": "^5.0.1", 35 | "rimraf": "^2.6.2" 36 | } 37 | } 38 | -------------------------------------------------------------------------------- /src/node/heartNode.js: -------------------------------------------------------------------------------- 1 | import Node from './node' 2 | 3 | export default class HeartNode extends Node { 4 | constructor(optiopn) { 5 | super(optiopn) 6 | this.width = optiopn.width || 120 7 | this.height = optiopn.height || 120 8 | } 9 | 10 | draw(ctx) { 11 | if (!this.visible) return; 12 | ctx.save(); 13 | ctx.beginPath(); 14 | ctx.fillStyle = 'rgba(' + this.style.fillStyle + ',' + this.alpha + ')'; 15 | ctx.moveTo(this.x + 75, this.y + 40); 16 | ctx.bezierCurveTo(this.x + 75, this.y + 37, this.x + 70, this.y + 25, this.x + 50, this.y + 25); 17 | ctx.bezierCurveTo(this.x + 20, this.y + 25, this.x + 20, this.y + 62.5, this.x + 20, this.y + 62.5); 18 | ctx.bezierCurveTo(this.x + 20, this.y + 80, this.x + 40, this.y + 102, this.x + 75, this.y + 120); 19 | ctx.bezierCurveTo(this.x + 110, this.y + 102, this.x + 130, this.y + 80, this.x + 130, this.y + 62.5); 20 | ctx.bezierCurveTo(this.x + 130, this.y + 62.5, this.x + 130, this.y + 25, this.x + 100, this.y + 25); 21 | ctx.bezierCurveTo(this.x + 85, this.y + 25, this.x + 75, this.y + 37, this.x + 75, this.y + 40); 22 | ctx.fill(); 23 | ctx.closePath(); 24 | ctx.restore(); 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /src/link/arrowsFoldLink.js: -------------------------------------------------------------------------------- 1 | import ArrowsLink from './arrowsLink' 2 | 3 | export default class ArrowsFoldLink extends ArrowsLink { 4 | constructor(nodeA, nodeB, name) { 5 | super(nodeA, nodeB) 6 | this.fold = 'x' 7 | this.angle = '0.4' 8 | this.offset = 10 9 | } 10 | 11 | draw(ctx) { 12 | let x1 = this.nodeA.x; 13 | let y1 = this.nodeA.y; 14 | let x2 = this.nodeB.x; 15 | let y2 = this.nodeB.y; 16 | let mx = x1; 17 | let my = y1; 18 | 19 | if (x1 == x2 || y1 == y2) { 20 | ctx.save(); 21 | super.draw(ctx) 22 | } else { 23 | if (this.fold == 'x') { 24 | mx = x1 + (x2 - x1); 25 | } else { 26 | my = y1 + (y2 - y1); 27 | } 28 | ctx.save(); 29 | ctx.beginPath(); 30 | ctx.strokeStyle = 'rgba(' + this.style.strokeStyle + ',' + this.style.alpha + ')'; 31 | ctx.lineWidth = this.style.lineWidth; 32 | ctx.moveTo(x1 + this.nodeA.width / 2, y1 + this.nodeA.height / 2); 33 | ctx.lineTo(mx + this.nodeA.width / 2, my + this.nodeA.height / 2); 34 | let ta = { x: mx + this.nodeA.width / 2, y: my + this.nodeA.height / 2 }; 35 | super.drawArrows(ctx, ta) 36 | ctx.stroke(); 37 | ctx.closePath(); 38 | ctx.restore(); 39 | } 40 | } 41 | } 42 | -------------------------------------------------------------------------------- /src/node/endPointNode.js: -------------------------------------------------------------------------------- 1 | import Node from './node' 2 | 3 | export default class EndPointNode extends Node { 4 | constructor(option) { 5 | super(option) 6 | this.r = option.r || 30 7 | this.beginDegree =option.beginDegree || 0 8 | let endDegree = option.endDegree || 2 9 | this.endDegree = endDegree * Math.PI 10 | } 11 | 12 | draw(ctx) { 13 | if (!this.visible) return; 14 | let points = []; 15 | 16 | let rx = node.width / 3; 17 | let ry = node.height / 3; 18 | function createPoint(x, y) { 19 | let point = new Node(); 20 | point.setSize(rx, ry); 21 | point.style.fillStyle = '0,255,0'; 22 | point.setDragable(false); 23 | point.setLocation(x, y); 24 | return point; 25 | } 26 | 27 | points.push(createPoint(this.x - rx / 2, this.y + this.height / 2 - ry / 2)); 28 | points.push(createPoint(this.x + this.width / 2 - rx / 2, this.y - ry / 2)); 29 | 30 | points.push(createPoint(this.x + this.width - rx / 2, this.y + this.height / 2 - ry / 2)); 31 | points.push(createPoint(this.x + this.width / 2 - rx / 2, this.y + this.height - ry / 2)); 32 | if (this.isSelected()) { 33 | for (let i = 0; i < points.length; i++) { 34 | points[i].draw(ctx); 35 | } 36 | } 37 | super.draw(ctx) 38 | } 39 | } 40 | -------------------------------------------------------------------------------- /demo/src/components/no-scale.vue: -------------------------------------------------------------------------------- 1 | 6 | 7 | 47 | -------------------------------------------------------------------------------- /src/node/textNode.js: -------------------------------------------------------------------------------- 1 | import Node from './node' 2 | 3 | export default class TextNode extends Node { 4 | constructor(optiopn) { 5 | super(optiopn) 6 | this.height = optiopn.height || 14 7 | this.style = optiopn.style || { strokeStyle: 'rgba(255,255,255, 0.99)', fillStyle: 'rgba(255,255,255, 0.5)' } 8 | } 9 | 10 | draw(ctx) { 11 | ctx.save(); 12 | ctx.beginPath(); 13 | ctx.font = this.style.fontSize + ' ' + this.style.font; 14 | var textWidth = ctx.measureText(this.name).width; 15 | ctx.closePath(); 16 | ctx.restore(); 17 | 18 | this.width = textWidth; 19 | if (!this.visible) return; 20 | 21 | if (this.selected) { 22 | var startx = this.x - (textWidth > this.width ? (textWidth - this.width) / 2 : 0); 23 | var width = Math.max(this.width, textWidth); 24 | ctx.save(); 25 | ctx.beginPath(); 26 | ctx.rect(startx - 3, this.y - 1, width + 6, this.height + 2); 27 | ctx.fill(); 28 | ctx.stroke(); 29 | ctx.closePath(); 30 | ctx.restore(); 31 | } 32 | ctx.save(); 33 | ctx.beginPath(); 34 | ctx.font = this.style.fontSize + ' ' + this.style.font; 35 | ctx.strokeStyle = this.style.strokeStyle; 36 | ctx.fillStyle = this.style.fillStyle; 37 | ctx.strokeText(this.name, this.x, this.y + 12); 38 | ctx.stroke(); 39 | ctx.fill(); 40 | ctx.closePath(); 41 | ctx.restore(); 42 | } 43 | } 44 | -------------------------------------------------------------------------------- /demo/build/build.js: -------------------------------------------------------------------------------- 1 | 'use strict' 2 | require('./check-versions')() 3 | 4 | process.env.NODE_ENV = 'production' 5 | 6 | const ora = require('ora') 7 | const rm = require('rimraf') 8 | const path = require('path') 9 | const chalk = require('chalk') 10 | const webpack = require('webpack') 11 | const config = require('../config') 12 | const webpackConfig = require('./webpack.prod.conf') 13 | 14 | const spinner = ora('building for production...') 15 | spinner.start() 16 | 17 | rm(path.join(config.build.assetsRoot, config.build.assetsSubDirectory), err => { 18 | if (err) throw err 19 | webpack(webpackConfig, (err, stats) => { 20 | spinner.stop() 21 | if (err) throw err 22 | process.stdout.write(stats.toString({ 23 | colors: true, 24 | modules: false, 25 | children: false, // If you are using ts-loader, setting this to true will make TypeScript errors show up during build. 26 | chunks: false, 27 | chunkModules: false 28 | }) + '\n\n') 29 | 30 | if (stats.hasErrors()) { 31 | console.log(chalk.red(' Build failed with errors.\n')) 32 | process.exit(1) 33 | } 34 | 35 | console.log(chalk.cyan(' Build complete.\n')) 36 | console.log(chalk.yellow( 37 | ' Tip: built files are meant to be served over an HTTP server.\n' + 38 | ' Opening index.html over file:// won\'t work.\n' 39 | )) 40 | }) 41 | }) 42 | -------------------------------------------------------------------------------- /demo/build/check-versions.js: -------------------------------------------------------------------------------- 1 | 'use strict' 2 | const chalk = require('chalk') 3 | const semver = require('semver') 4 | const packageConfig = require('../package.json') 5 | const shell = require('shelljs') 6 | 7 | function exec (cmd) { 8 | return require('child_process').execSync(cmd).toString().trim() 9 | } 10 | 11 | const versionRequirements = [ 12 | { 13 | name: 'node', 14 | currentVersion: semver.clean(process.version), 15 | versionRequirement: packageConfig.engines.node 16 | } 17 | ] 18 | 19 | if (shell.which('npm')) { 20 | versionRequirements.push({ 21 | name: 'npm', 22 | currentVersion: exec('npm --version'), 23 | versionRequirement: packageConfig.engines.npm 24 | }) 25 | } 26 | 27 | module.exports = function () { 28 | const warnings = [] 29 | 30 | for (let i = 0; i < versionRequirements.length; i++) { 31 | const mod = versionRequirements[i] 32 | 33 | if (!semver.satisfies(mod.currentVersion, mod.versionRequirement)) { 34 | warnings.push(mod.name + ': ' + 35 | chalk.red(mod.currentVersion) + ' should be ' + 36 | chalk.green(mod.versionRequirement) 37 | ) 38 | } 39 | } 40 | 41 | if (warnings.length) { 42 | console.log('') 43 | console.log(chalk.yellow('To use this template, you must update following to modules:')) 44 | console.log() 45 | 46 | for (let i = 0; i < warnings.length; i++) { 47 | const warning = warnings[i] 48 | console.log(' ' + warning) 49 | } 50 | 51 | console.log() 52 | process.exit(1) 53 | } 54 | } 55 | -------------------------------------------------------------------------------- /demo/src/components/link.vue: -------------------------------------------------------------------------------- 1 | 6 | 65 | -------------------------------------------------------------------------------- /src/link/arrowsLink.js: -------------------------------------------------------------------------------- 1 | import Link from './link' 2 | 3 | export default class ArrowsLink extends Link { 4 | constructor(nodeA, nodeB, name) { 5 | super(nodeA, nodeB) 6 | this.angle = '0.4' 7 | this.offset = 10 8 | } 9 | 10 | /** 11 | * 画箭头 12 | * @param {Object} ctx 13 | * @param {Object} ta 移到的距离 14 | */ 15 | drawArrows(ctx, ta) { 16 | let t = { x: this.nodeB.x + this.nodeB.width / 2, y: this.nodeB.y + this.nodeB.height / 2 }; 17 | let angle = Math.atan2(ta.y - t.y, ta.x - t.x); 18 | t.x = t.x + Math.cos(angle) * this.nodeB.width / 2; 19 | t.y = t.y + Math.sin(angle) * this.nodeB.height / 2; 20 | 21 | let da = 0.4; 22 | let pointA = { 23 | x: t.x + Math.cos(angle - da) * this.offset, 24 | y: t.y + Math.sin(angle - da) * this.offset 25 | }; 26 | 27 | let pointB = { 28 | x: t.x + Math.cos(angle + da) * this.offset, 29 | y: t.y + Math.sin(angle + da) * this.offset 30 | }; 31 | 32 | //ctx.lineTo(this.nodeB.x + this.nodeB.width / 2, this.nodeB.y + this.nodeB.height / 2); 33 | ctx.lineTo(t.x, t.y); 34 | ctx.lineTo(pointB.x, pointB.y); 35 | ctx.moveTo(t.x, t.y); 36 | ctx.lineTo(pointA.x, pointA.y); 37 | if (this.style.fillStyle != null) { 38 | ctx.fill(); 39 | } 40 | } 41 | 42 | draw(ctx) { 43 | ctx.save(); 44 | ctx.beginPath(); 45 | ctx.strokeStyle = 'rgba(' + this.style.strokeStyle + ',' + this.style.alpha + ')'; 46 | ctx.fillStyle = 'rgba(' + this.style.fillStyle + ',' + this.style.alpha + ')'; 47 | ctx.lineWidth = this.style.lineWidth; 48 | ctx.moveTo(this.nodeA.x + this.nodeA.width / 2, this.nodeA.y + this.nodeA.height / 2); 49 | let ta = { x: this.nodeA.x + this.nodeA.width / 2, y: this.nodeA.y + this.nodeA.height / 2 }; 50 | this.drawArrows(ctx, ta) 51 | ctx.stroke(); 52 | ctx.closePath(); 53 | ctx.restore(); 54 | } 55 | } 56 | -------------------------------------------------------------------------------- /demo/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "y", 3 | "version": "1.0.0", 4 | "description": "A Vue.js project", 5 | "author": "oo2o", 6 | "private": true, 7 | "scripts": { 8 | "dev": "webpack-dev-server --inline --progress --config build/webpack.dev.conf.js", 9 | "start": "npm run dev", 10 | "build": "node build/build.js" 11 | }, 12 | "dependencies": { 13 | "vue": "^2.5.2", 14 | "vue-router": "^3.0.1" 15 | }, 16 | "devDependencies": { 17 | "autoprefixer": "^7.1.2", 18 | "babel-core": "^6.22.1", 19 | "babel-helper-vue-jsx-merge-props": "^2.0.3", 20 | "babel-loader": "^7.1.1", 21 | "babel-plugin-syntax-jsx": "^6.18.0", 22 | "babel-plugin-transform-runtime": "^6.22.0", 23 | "babel-plugin-transform-vue-jsx": "^3.5.0", 24 | "babel-preset-env": "^1.3.2", 25 | "babel-preset-stage-2": "^6.22.0", 26 | "chalk": "^2.0.1", 27 | "copy-webpack-plugin": "^4.0.1", 28 | "css-loader": "^0.28.0", 29 | "extract-text-webpack-plugin": "^3.0.0", 30 | "file-loader": "^1.1.4", 31 | "friendly-errors-webpack-plugin": "^1.6.1", 32 | "html-webpack-plugin": "^2.30.1", 33 | "node-notifier": "^5.1.2", 34 | "optimize-css-assets-webpack-plugin": "^3.2.0", 35 | "ora": "^1.2.0", 36 | "portfinder": "^1.0.13", 37 | "postcss-import": "^11.0.0", 38 | "postcss-loader": "^2.0.8", 39 | "postcss-url": "^7.2.1", 40 | "rimraf": "^2.6.0", 41 | "semver": "^5.3.0", 42 | "shelljs": "^0.7.6", 43 | "uglifyjs-webpack-plugin": "^1.1.1", 44 | "url-loader": "^0.5.8", 45 | "vue-loader": "^13.3.0", 46 | "vue-style-loader": "^3.0.1", 47 | "vue-template-compiler": "^2.5.2", 48 | "webpack": "^3.6.0", 49 | "webpack-bundle-analyzer": "^2.9.0", 50 | "webpack-dev-server": "^2.9.1", 51 | "webpack-merge": "^4.1.0" 52 | }, 53 | "engines": { 54 | "node": ">= 6.0.0", 55 | "npm": ">= 3.0.0" 56 | }, 57 | "browserslist": [ 58 | "> 1%", 59 | "last 2 versions", 60 | "not ie <= 8" 61 | ] 62 | } 63 | -------------------------------------------------------------------------------- /src/node/abstractNode.js: -------------------------------------------------------------------------------- 1 | 2 | import Element from '../element' 3 | import Tips from './tips' 4 | let ImageCache = {} 5 | export default class AbstractNode extends Element { 6 | constructor(option){ 7 | super() 8 | this.id = option.id || null; 9 | this.x = option.x || 0; 10 | this.y = option.y || 0; 11 | this.width = option.width || 0; 12 | this.height = option.height || 0; 13 | this.visible = option.visible || true; 14 | this.dragable = option.dragable || true; 15 | this.text = option.text || option.name || '' 16 | this.name = option.name || ''; 17 | this.image = option.image || null; 18 | this.color = option.color || null; 19 | this.layout = option.layout || null; 20 | this.gravitate = option.gravitate || null;//function(){}; 21 | this.parentContainer = option.parentContainer || null; 22 | this.inContainer = option.inContainer || null; 23 | this.outContainer = option.outContainer || null; 24 | this.fixed = option.fixed || false; 25 | this.tip = new Tips(option.tip || {}) 26 | } 27 | 28 | draw(ctx){ 29 | 30 | } 31 | 32 | getName = function(){ 33 | return this.name; 34 | } 35 | 36 | setName = function(n){ 37 | this.name = n; 38 | return this; 39 | } 40 | 41 | getImage = function(){ 42 | return this.image; 43 | } 44 | 45 | setImage = function(i){ 46 | let node = this; 47 | if(typeof i == 'string'){ 48 | let img = this.image = new Image(); 49 | this.image.onload = function(){ 50 | node.setSize(img.width, img.height); 51 | }; 52 | this.image.src = i; 53 | }else{ 54 | this.image = i; 55 | } 56 | } 57 | 58 | getTypeImage = function(type){ 59 | let typeImages = { 60 | 'zone' : './img/zone.png', 61 | 'host' : './img/host.png', 62 | 'vm' : './img/vm.png' 63 | }; 64 | if(ImageCache[type]){ 65 | return ImageCache[type]; 66 | } 67 | let src = typeImages[type]; 68 | if(src == null) return null; 69 | 70 | let image = new Image(); 71 | image.src = src; 72 | return ImageCache[type] = image; 73 | } 74 | 75 | getType = function(){ 76 | return this.type; 77 | } 78 | 79 | setType = function(type){ 80 | this.type = type; 81 | this.setImage(this.getTypeImage(type)); 82 | } 83 | 84 | } 85 | -------------------------------------------------------------------------------- /demo/src/components/app.vue: -------------------------------------------------------------------------------- 1 | 6 | 7 | 80 | 83 | -------------------------------------------------------------------------------- /demo/config/index.js: -------------------------------------------------------------------------------- 1 | 'use strict' 2 | // Template version: 1.3.1 3 | // see http://vuejs-templates.github.io/webpack for documentation. 4 | 5 | const path = require('path') 6 | 7 | module.exports = { 8 | dev: { 9 | 10 | // Paths 11 | assetsSubDirectory: 'static', 12 | assetsPublicPath: '/', 13 | proxyTable: {}, 14 | 15 | // Various Dev Server settings 16 | host: 'localhost', // can be overwritten by process.env.HOST 17 | port: 3010, // can be overwritten by process.env.PORT, if port is in use, a free one will be determined 18 | autoOpenBrowser: false, 19 | errorOverlay: true, 20 | notifyOnErrors: true, 21 | poll: false, // https://webpack.js.org/configuration/dev-server/#devserver-watchoptions- 22 | 23 | 24 | /** 25 | * Source Maps 26 | */ 27 | 28 | // https://webpack.js.org/configuration/devtool/#development 29 | devtool: 'cheap-module-eval-source-map', 30 | 31 | // If you have problems debugging vue-files in devtools, 32 | // set this to false - it *may* help 33 | // https://vue-loader.vuejs.org/en/options.html#cachebusting 34 | cacheBusting: true, 35 | 36 | cssSourceMap: true 37 | }, 38 | 39 | build: { 40 | // Template for index.html 41 | index: path.resolve(__dirname, '../dist/index.html'), 42 | 43 | // Paths 44 | assetsRoot: path.resolve(__dirname, '../dist'), 45 | assetsSubDirectory: 'static', 46 | assetsPublicPath: '/', 47 | 48 | /** 49 | * Source Maps 50 | */ 51 | 52 | productionSourceMap: true, 53 | // https://webpack.js.org/configuration/devtool/#production 54 | devtool: '#source-map', 55 | 56 | // Gzip off by default as many popular static hosts such as 57 | // Surge or Netlify already gzip all static assets for you. 58 | // Before setting to `true`, make sure to: 59 | // npm install --save-dev compression-webpack-plugin 60 | productionGzip: false, 61 | productionGzipExtensions: ['js', 'css'], 62 | 63 | // Run the build command with an extra argument to 64 | // View the bundle analyzer report after build finishes: 65 | // `npm run build --report` 66 | // Set to `true` or `false` to always turn it on or off 67 | bundleAnalyzerReport: process.env.npm_config_report 68 | } 69 | } 70 | -------------------------------------------------------------------------------- /demo/build/webpack.base.conf.js: -------------------------------------------------------------------------------- 1 | 'use strict' 2 | const path = require('path') 3 | const utils = require('./utils') 4 | const config = require('../config') 5 | const vueLoaderConfig = require('./vue-loader.conf') 6 | 7 | function resolve (dir) { 8 | return path.join(__dirname, '..', dir) 9 | } 10 | 11 | 12 | 13 | module.exports = { 14 | context: path.resolve(__dirname, '../'), 15 | entry: { 16 | app: './src/main.js' 17 | }, 18 | output: { 19 | path: config.build.assetsRoot, 20 | filename: '[name].js', 21 | publicPath: process.env.NODE_ENV === 'production' 22 | ? config.build.assetsPublicPath 23 | : config.dev.assetsPublicPath 24 | }, 25 | resolve: { 26 | extensions: ['.js', '.vue', '.json'], 27 | alias: { 28 | 'vue$': 'vue/dist/vue.esm.js', 29 | '@': resolve('src'), 30 | 'JTopo': resolve('../src/') 31 | } 32 | }, 33 | module: { 34 | rules: [ 35 | { 36 | test: /\.vue$/, 37 | loader: 'vue-loader', 38 | options: vueLoaderConfig 39 | }, 40 | { 41 | test: /\.js$/, 42 | loader: 'babel-loader', 43 | exclude: /node_modules/ 44 | }, 45 | { 46 | test: /\.(png|jpe?g|gif|svg)(\?.*)?$/, 47 | loader: 'url-loader', 48 | options: { 49 | limit: 10000, 50 | name: utils.assetsPath('img/[name].[hash:7].[ext]') 51 | } 52 | }, 53 | { 54 | test: /\.(mp4|webm|ogg|mp3|wav|flac|aac)(\?.*)?$/, 55 | loader: 'url-loader', 56 | options: { 57 | limit: 10000, 58 | name: utils.assetsPath('media/[name].[hash:7].[ext]') 59 | } 60 | }, 61 | { 62 | test: /\.(woff2?|eot|ttf|otf)(\?.*)?$/, 63 | loader: 'url-loader', 64 | options: { 65 | limit: 10000, 66 | name: utils.assetsPath('fonts/[name].[hash:7].[ext]') 67 | } 68 | } 69 | ] 70 | }, 71 | node: { 72 | // prevent webpack from injecting useless setImmediate polyfill because Vue 73 | // source contains it (although only uses it if it's native). 74 | setImmediate: false, 75 | // prevent webpack from injecting mocks to Node native modules 76 | // that does not make sense for the client 77 | dgram: 'empty', 78 | fs: 'empty', 79 | net: 'empty', 80 | tls: 'empty', 81 | child_process: 'empty' 82 | } 83 | } 84 | -------------------------------------------------------------------------------- /src/container/gridContainer.js: -------------------------------------------------------------------------------- 1 | import Container from './container' 2 | 3 | export default class GridContainer extends Container { 4 | constructor() { 5 | super() 6 | this.rows = 3; 7 | this.cols = 2; 8 | this.cellWidth = 60; 9 | this.cellHeight = 60; 10 | this.offset = 3 11 | } 12 | 13 | adjustLayout() { 14 | for (let i = 0; i < this.items.length; i++) { 15 | let item = this.items[i]; 16 | let row = Math.floor(i / this.cols); 17 | let col = i % this.cols; 18 | item.x = this.x + col * this.cellWidth; 19 | item.y = this.y + row * this.cellHeight; 20 | } 21 | }; 22 | 23 | add(e) { 24 | let capacity = this.items.length; 25 | if (capacity == this.rows * this.cols) return; 26 | this.items.push(e); 27 | e.parentContainer = this; 28 | this.adjustLayout(); 29 | }; 30 | 31 | draw(ctx) { 32 | this.width = this.cols * this.cellWidth; 33 | this.height = this.rows * this.cellHeight; 34 | ctx.save(); 35 | ctx.beginPath(); 36 | ctx.shadowBlur = 12; 37 | ctx.shadowColor = 'rgba(0,0,0,0.9)'; 38 | ctx.shadowOffsetX = 5; 39 | ctx.shadowOffsetY = 3; 40 | ctx.fillStyle = 'rgba(' + this.style.fillStyle + ',' + this.alpha + ')'; 41 | 42 | let r = 0; 43 | if (this.isFocus()) { 44 | r = this.offset; 45 | ctx.shadowColor = 'rgba(0,0,200, 1)'; 46 | ctx.fillRect(this.x - r, this.y - r, this.width + r * 2, this.height + r * 2); 47 | } else { 48 | ctx.shadowColor = 'rgba(0,0,0,0.5)'; 49 | ctx.fillRect(this.x, this.y, this.width, this.height); 50 | } 51 | /* 52 | ctx.moveTo(this.x-r, this.y -r); 53 | ctx.lineTo(this.x-r + 10, this.y - 10 -r); 54 | ctx.lineTo(this.x-r + 10 + this.width, this.y - 10-r); 55 | ctx.lineTo(this.x-r + 10 + this.width, this.y + this.height - 10 -r); 56 | ctx.lineTo(this.x-r + this.width, this.y + this.height -r); 57 | ctx.moveTo(this.x-r + 10 + this.width, this.y - 10 -r); 58 | ctx.lineTo(this.x-r + this.width, this.y -r); 59 | 60 | for(let i=0; i<=this.rows; i++){ 61 | for(let j=0; j 0) { 54 | let minX = 10000000; 55 | let maxX = -10000000; 56 | let minY = 10000000; 57 | let maxY = -10000000; 58 | let width = maxX - minX; 59 | let height = maxY - minY; 60 | for (let i = 0; i < this.items.length; i++) { 61 | let item = this.items[i]; 62 | if (item.x <= minX) { 63 | minX = item.x; 64 | } 65 | if (item.x >= maxX) { 66 | maxX = item.x; 67 | } 68 | if (item.y <= minY) { 69 | minY = item.y; 70 | } 71 | if (item.y >= maxY) { 72 | maxY = item.y; 73 | } 74 | width = maxX - minX + item.width; 75 | height = maxY - minY + item.height; 76 | } 77 | 78 | this.x = minX - 5; 79 | this.y = minY - 5; 80 | this.width = width + 5; 81 | this.height = height + 5; 82 | } 83 | } 84 | 85 | draw(ctx) { 86 | this.updateBound(); 87 | ctx.save(); 88 | ctx.beginPath(); 89 | ctx.shadowBlur = 9; 90 | ctx.shadowColor = 'rgba(0,0,0,0.5)'; 91 | ctx.shadowOffsetX = 3; 92 | ctx.shadowOffsetY = 3; 93 | ctx.fillStyle = 'rgba(' + this.style.fillStyle + ',' + this.alpha + ')'; 94 | ctx.fillRect(this.x, this.y, this.width, this.height); 95 | ctx.closePath(); 96 | ctx.restore(); 97 | } 98 | 99 | } 100 | -------------------------------------------------------------------------------- /src/node/tips.js: -------------------------------------------------------------------------------- 1 | export default class Tips { 2 | constructor(option) { 3 | this.width = option.width || 0; 4 | this.height = option.height || 0; 5 | this.style = option.style || { fontSize: 10, font: '' } 6 | this.alpha = option.alpha || 1 7 | this.strokeStyle = option.strokeStyle || 'rgba(230, 230, 230, ' + this.alpha + ')' 8 | this.direction = option.direction || 'Top' 9 | this.type = option.type || 'Top' 10 | this.text = option.text || null 11 | } 12 | 13 | draw(ctx, node) { 14 | switch (this.type) { 15 | case 'Top': 16 | this.drawTop(ctx, node) 17 | break 18 | case 'Bottom': 19 | this.drawBottom(ctx, node) 20 | break; 21 | case 'Left': 22 | this.drawLeft(ctx, node) 23 | break; 24 | case 'Right': 25 | this.drawRight(ctx, node) 26 | break; 27 | default: 28 | this.drawTop(ctx, node) 29 | break; 30 | } 31 | } 32 | 33 | drawTop(ctx, node) { 34 | if (!this.text || this.text == '') return; 35 | let textWidth = ctx.measureText(this.text).width; 36 | let ds = (node.width - textWidth) / 2 37 | ctx.save(); 38 | ctx.beginPath(); 39 | ctx.font = this.style.fontSize + ' ' + this.style.font; 40 | ctx.strokeStyle = this.strokeStyle; 41 | ctx.strokeText(this.text, -node.width / 2 + ds, -node.height - 5); // 文本内容 42 | ctx.moveTo(-node.width / 2 - 2 + ds, -node.height - 20) // 移到左上点 43 | ctx.lineTo(-node.width / 2 + 2 + textWidth + ds, -node.height - 20) // 画到右边 44 | ctx.lineTo(-node.width / 2 + 2 + textWidth + ds, -node.height + 5) // 画到右下点 45 | ctx.lineTo((-node.width / 2 + 2 + textWidth / 2) + ds + 4, -node.height + 5) // 画到口边 46 | ctx.lineTo((-node.width / 2 + 2 + textWidth / 2) - 2 + ds, -node.height + 10) 47 | ctx.lineTo((-node.width / 2 + 2 + textWidth / 2) - 10 + ds, -node.height + 5) 48 | ctx.lineTo(-node.width / 2 - 2 + ds, -node.height + 5) 49 | ctx.closePath(); 50 | ctx.stroke(); 51 | ctx.restore(); 52 | } 53 | 54 | drawLeft(ctx) { 55 | if (!this.text || this.text == '') return; 56 | // let textWidth = ctx.measureText(this.text).width; 57 | // let ds = (node.width - textWidth) / 2 58 | // ctx.save(); 59 | // ctx.beginPath(); 60 | // ctx.font = this.style.fontSize + ' ' + this.style.font; 61 | // ctx.strokeStyle = this.strokeStyle; 62 | // ctx.strokeText(this.text, -node.width / 2 + ds, -node.height - 5); // 文本内容 63 | // ctx.moveTo(-node.width / 2 - 2 + ds, -node.height - 20) // 移到左上点 64 | // ctx.lineTo(-node.width / 2 + 2 + textWidth + ds, -node.height - 20) // 画到右边 65 | // ctx.lineTo(-node.width / 2 + 2 + textWidth + ds, -node.height + 5) // 画到右下点 66 | // ctx.lineTo((-node.width / 2 + 2 + textWidth / 2) + ds + 4, -node.height + 5) // 画到口边 67 | // ctx.lineTo((-node.width / 2 + 2 + textWidth / 2) - 2 + ds, -node.height + 10) 68 | // ctx.lineTo((-node.width / 2 + 2 + textWidth / 2) - 10 + ds, -node.height + 5) 69 | // ctx.lineTo(-node.width / 2 - 2 + ds, -node.height + 5) 70 | // ctx.closePath(); 71 | // ctx.stroke(); 72 | // ctx.restore(); 73 | } 74 | 75 | drawBottom(ctx) { 76 | 77 | } 78 | 79 | drwaRight(ctx) { 80 | 81 | } 82 | } 83 | -------------------------------------------------------------------------------- /demo/build/utils.js: -------------------------------------------------------------------------------- 1 | 'use strict' 2 | const path = require('path') 3 | const config = require('../config') 4 | const ExtractTextPlugin = require('extract-text-webpack-plugin') 5 | const packageConfig = require('../package.json') 6 | 7 | exports.assetsPath = function (_path) { 8 | const assetsSubDirectory = process.env.NODE_ENV === 'production' 9 | ? config.build.assetsSubDirectory 10 | : config.dev.assetsSubDirectory 11 | 12 | return path.posix.join(assetsSubDirectory, _path) 13 | } 14 | 15 | exports.cssLoaders = function (options) { 16 | options = options || {} 17 | 18 | const cssLoader = { 19 | loader: 'css-loader', 20 | options: { 21 | sourceMap: options.sourceMap 22 | } 23 | } 24 | 25 | const postcssLoader = { 26 | loader: 'postcss-loader', 27 | options: { 28 | sourceMap: options.sourceMap 29 | } 30 | } 31 | 32 | // generate loader string to be used with extract text plugin 33 | function generateLoaders (loader, loaderOptions) { 34 | const loaders = options.usePostCSS ? [cssLoader, postcssLoader] : [cssLoader] 35 | 36 | if (loader) { 37 | loaders.push({ 38 | loader: loader + '-loader', 39 | options: Object.assign({}, loaderOptions, { 40 | sourceMap: options.sourceMap 41 | }) 42 | }) 43 | } 44 | 45 | // Extract CSS when that option is specified 46 | // (which is the case during production build) 47 | if (options.extract) { 48 | return ExtractTextPlugin.extract({ 49 | use: loaders, 50 | fallback: 'vue-style-loader' 51 | }) 52 | } else { 53 | return ['vue-style-loader'].concat(loaders) 54 | } 55 | } 56 | 57 | // https://vue-loader.vuejs.org/en/configurations/extract-css.html 58 | return { 59 | css: generateLoaders(), 60 | postcss: generateLoaders(), 61 | less: generateLoaders('less'), 62 | sass: generateLoaders('sass', { indentedSyntax: true }), 63 | scss: generateLoaders('sass'), 64 | stylus: generateLoaders('stylus'), 65 | styl: generateLoaders('stylus') 66 | } 67 | } 68 | 69 | // Generate loaders for standalone style files (outside of .vue) 70 | exports.styleLoaders = function (options) { 71 | const output = [] 72 | const loaders = exports.cssLoaders(options) 73 | 74 | for (const extension in loaders) { 75 | const loader = loaders[extension] 76 | output.push({ 77 | test: new RegExp('\\.' + extension + '$'), 78 | use: loader 79 | }) 80 | } 81 | 82 | return output 83 | } 84 | 85 | exports.createNotifierCallback = () => { 86 | const notifier = require('node-notifier') 87 | 88 | return (severity, errors) => { 89 | if (severity !== 'error') return 90 | 91 | const error = errors[0] 92 | const filename = error.file && error.file.split('!').pop() 93 | 94 | notifier.notify({ 95 | title: packageConfig.name, 96 | message: severity + ': ' + error.name, 97 | subtitle: filename || '', 98 | icon: path.join(__dirname, 'logo.png') 99 | }) 100 | } 101 | } 102 | -------------------------------------------------------------------------------- /src/util.js: -------------------------------------------------------------------------------- 1 | const Util = { 2 | drawStart(ctx) { 3 | ctx.save(); 4 | ctx.beginPath(); 5 | }, 6 | drawEnd() { 7 | ctx.stroke(); 8 | ctx.closePath(); 9 | ctx.restore(); 10 | }, 11 | getDistance(p1, p2) { 12 | let dx = p2.x - p1.x; 13 | let dy = p2.y - p1.y; 14 | return Math.sqrt(dx * dx + dy * dy); 15 | }, 16 | mouseCoords(event) { 17 | if (event.pageX || event.pageY) { 18 | return { x: event.pageX, y: event.pageY }; 19 | } 20 | return { 21 | x: event.clientX + document.body.scrollLeft - document.body.clientLeft, 22 | y: event.clientY + document.body.scrollTop - document.body.clientTop 23 | }; 24 | }, 25 | getXY(box, event) { 26 | event = event || mouseCoords(window.event); 27 | let x = document.body.scrollLeft + (event.x || event.layerX); 28 | let y = document.body.scrollTop + (event.y || event.layerY); 29 | return { x: x - box.offset.left, y: y - box.offset.top }; 30 | }, 31 | rotatePoint(bx, by, x, y, angle) { 32 | let dx = x - bx; 33 | let dy = y - by; 34 | let r = Math.sqrt(dx * dx + dy * dy); 35 | let a = Math.atan2(dy, dx) + angle; 36 | return { 37 | x: bx + Math.cos(a) * r, 38 | y: by + Math.sin(a) * r 39 | }; 40 | }, 41 | rotatePoints(target, points, angle) { 42 | let result = []; 43 | for (let i = 0; i < points.length; i++) { 44 | let p = rotatePoint(target.x, target.y, points[i].x, points[i].y, angle); 45 | result.push(p); 46 | } 47 | return result; 48 | } 49 | } 50 | 51 | class MessageBus { 52 | constructor(name) { 53 | this.name = name; 54 | this.messageMap = {}; 55 | this.messageCount = 0; 56 | } 57 | subscribe(topic, action) { 58 | if (! typeof topic == 'string') { 59 | this.subscribes(topic, action); 60 | } else { 61 | var actions = this.messageMap[topic]; 62 | if (actions == null) { 63 | this.messageMap[topic] = []; 64 | } 65 | this.messageMap[topic].push(action); 66 | this.messageCount++; 67 | } 68 | } 69 | subscribes(topics, action) { 70 | var results = []; 71 | var counter = 0; 72 | for (var i = 0; i < topics.length; i++) { 73 | var topic = topics[i]; 74 | var actions = this.messageMap[topic]; 75 | if (actions == null) { 76 | this.messageMap[topic] = []; 77 | } 78 | function actionProxy(result) { 79 | results[i] = result; 80 | counter++; 81 | if (counter == topics.length) { 82 | counter = 0; 83 | return action.apply(null, results); 84 | } else { 85 | return null; 86 | } 87 | }; 88 | 89 | this.messageMap[topic].push(actionProxy); 90 | this.messageCount++; 91 | } 92 | } 93 | unsubscribe(topic) { 94 | var actions = this.messageMap[topic]; 95 | if (actions != null) { 96 | this.messageMap[topic] = null; 97 | delete (this.messageMap[topic]); 98 | this.messageCount--; 99 | } 100 | } 101 | publish(topic, data, concurrency) { 102 | var actions = this.messageMap[topic]; 103 | if (actions != null) { 104 | for (var i = 0; i < actions.length; i++) { 105 | if (concurrency) { 106 | (function (action, data) { 107 | setTimeout(function () { action(data); }, 10); 108 | })(actions[i], data); 109 | } else { 110 | actions[i](data); 111 | } 112 | } 113 | } 114 | } 115 | } 116 | 117 | export default { MessageBus, ...Util } 118 | -------------------------------------------------------------------------------- /src/node/node.js: -------------------------------------------------------------------------------- 1 | import AbstractNode from './abstractNode' 2 | 3 | export default class Node extends AbstractNode { 4 | 5 | constructor(option) { 6 | super(option) 7 | this.name = option.name || ''; 8 | this.width = 35; 9 | this.height = 35; 10 | this.style = { fillStyle: '71, 167, 184', fontSize: '10pt', font: "Consolas" }; 11 | this.type = null; 12 | this.selected = false; 13 | 14 | this.alpha = 1; 15 | this.scala = 1; 16 | this.rotate = 0 17 | } 18 | 19 | drawText(ctx) { 20 | let text = this.text; 21 | if (!text || text == '') return; 22 | let textWidth = ctx.measureText(text).width; 23 | ctx.font = this.style.fontSize + ' ' + this.style.font; 24 | ctx.strokeStyle = 'rgba(230, 230, 230, ' + this.alpha + ')'; 25 | ctx.strokeText(text, -this.width / 2 + (this.width - textWidth) / 2, this.height / 2 + 12); 26 | } 27 | 28 | drawTip(ctx) { 29 | 30 | } 31 | 32 | drawSelectedRect(ctx) { 33 | var textWidth = ctx.measureText(this.name).width; 34 | var w = this.width 35 | ctx.save(); 36 | ctx.beginPath(); 37 | ctx.strokeStyle = 'rgba(168,202,255, 0.9)'; 38 | ctx.fillStyle = 'rgba(168,202,236,0.5)'; 39 | ctx.rect(-w / 2 - 2, -this.height / 2 - 2, w + 4, this.height + 4); 40 | ctx.fill(); 41 | ctx.stroke(); 42 | ctx.closePath(); 43 | ctx.restore(); 44 | } 45 | 46 | draw(ctx) { 47 | if (!this.isVisible) return; 48 | ctx.save(); 49 | ctx.translate(this.x + this.width / 2, this.y + this.height / 2); 50 | ctx.rotate(this.rotate); 51 | 52 | if (this.selected || this.focus) { 53 | this.drawSelectedRect(ctx); 54 | } 55 | let image = this.getImage(); 56 | if (image != null) { 57 | //ctx.rect(-this.width/2, -this.height/2, this.width, this.height); 58 | //ctx.clip(); 59 | ctx.drawImage(image, -this.width / 2, -this.height / 2); 60 | } else { 61 | ctx.beginPath(); 62 | ctx.fillStyle = 'rgba(' + this.style.fillStyle + ',' + this.alpha + ')'; 63 | ctx.rect(-this.width / 2, -this.height / 2, this.width, this.height); 64 | ctx.fill(); 65 | ctx.closePath(); 66 | } 67 | this.drawText(ctx); 68 | if (this.isTipVisible) { 69 | this.tip.draw(ctx, this); 70 | } 71 | ctx.restore(); 72 | } 73 | 74 | split(angle) { 75 | let node = this; 76 | function genNode(x, y, r, beginDegree, endDegree) { 77 | let newNode = new JTopo.Node(); 78 | newNode.setImage(node.image); 79 | newNode.setLocation(x, y); 80 | newNode.draw = function (ctx) { 81 | ctx.save(); 82 | ctx.arc(this.x + this.width / 2, this.y + this.height / 2, r, beginDegree, endDegree); 83 | ctx.clip(); 84 | ctx.beginPath(); 85 | if (this.image != null) { 86 | ctx.drawImage(this.image, this.x, this.y); 87 | } else { 88 | ctx.fillStyle = 'rgba(' + this.style.fillStyle + ',' + this.alpha + ')'; 89 | ctx.rect(this.x, this.y, this.width, this.height); 90 | ctx.fill(); 91 | } 92 | ctx.closePath(); 93 | ctx.restore(); 94 | }; 95 | return newNode; 96 | }; 97 | let beginDegree = angle; 98 | let endDegree = angle + Math.PI; 99 | 100 | let nodeA = genNode(node.x, node.y, node.width, beginDegree, endDegree); 101 | let nodeB = genNode(node.x, node.y, node.width, beginDegree + Math.PI, beginDegree); 102 | 103 | return { 104 | nodeA: nodeA, 105 | nodeB: nodeB 106 | }; 107 | } 108 | } 109 | -------------------------------------------------------------------------------- /demo/build/webpack.dev.conf.js: -------------------------------------------------------------------------------- 1 | 'use strict' 2 | const utils = require('./utils') 3 | const webpack = require('webpack') 4 | const config = require('../config') 5 | const merge = require('webpack-merge') 6 | const path = require('path') 7 | const baseWebpackConfig = require('./webpack.base.conf') 8 | const CopyWebpackPlugin = require('copy-webpack-plugin') 9 | const HtmlWebpackPlugin = require('html-webpack-plugin') 10 | const FriendlyErrorsPlugin = require('friendly-errors-webpack-plugin') 11 | const portfinder = require('portfinder') 12 | 13 | const HOST = process.env.HOST 14 | const PORT = process.env.PORT && Number(process.env.PORT) 15 | 16 | const devWebpackConfig = merge(baseWebpackConfig, { 17 | module: { 18 | rules: utils.styleLoaders({ sourceMap: config.dev.cssSourceMap, usePostCSS: true }) 19 | }, 20 | // cheap-module-eval-source-map is faster for development 21 | devtool: config.dev.devtool, 22 | 23 | // these devServer options should be customized in /config/index.js 24 | devServer: { 25 | clientLogLevel: 'warning', 26 | historyApiFallback: { 27 | rewrites: [ 28 | { from: /.*/, to: path.posix.join(config.dev.assetsPublicPath, 'index.html') }, 29 | ], 30 | }, 31 | hot: true, 32 | contentBase: false, // since we use CopyWebpackPlugin. 33 | compress: true, 34 | host: HOST || config.dev.host, 35 | port: PORT || config.dev.port, 36 | open: config.dev.autoOpenBrowser, 37 | overlay: config.dev.errorOverlay 38 | ? { warnings: false, errors: true } 39 | : false, 40 | publicPath: config.dev.assetsPublicPath, 41 | proxy: config.dev.proxyTable, 42 | quiet: true, // necessary for FriendlyErrorsPlugin 43 | watchOptions: { 44 | poll: config.dev.poll, 45 | } 46 | }, 47 | plugins: [ 48 | new webpack.DefinePlugin({ 49 | 'process.env': require('../config/dev.env') 50 | }), 51 | new webpack.HotModuleReplacementPlugin(), 52 | new webpack.NamedModulesPlugin(), // HMR shows correct file names in console on update. 53 | new webpack.NoEmitOnErrorsPlugin(), 54 | // https://github.com/ampedandwired/html-webpack-plugin 55 | new HtmlWebpackPlugin({ 56 | filename: 'index.html', 57 | template: 'index.html', 58 | inject: true 59 | }), 60 | // copy custom static assets 61 | new CopyWebpackPlugin([ 62 | { 63 | from: path.resolve(__dirname, '../static'), 64 | to: config.dev.assetsSubDirectory, 65 | ignore: ['.*'] 66 | } 67 | ]) 68 | ] 69 | }) 70 | 71 | module.exports = new Promise((resolve, reject) => { 72 | portfinder.basePort = process.env.PORT || config.dev.port 73 | portfinder.getPort((err, port) => { 74 | if (err) { 75 | reject(err) 76 | } else { 77 | // publish the new Port, necessary for e2e tests 78 | process.env.PORT = port 79 | // add port to devServer config 80 | devWebpackConfig.devServer.port = port 81 | 82 | // Add FriendlyErrorsPlugin 83 | devWebpackConfig.plugins.push(new FriendlyErrorsPlugin({ 84 | compilationSuccessInfo: { 85 | messages: [`Your application is running here: http://${devWebpackConfig.devServer.host}:${port}`], 86 | }, 87 | onErrors: config.dev.notifyOnErrors 88 | ? utils.createNotifierCallback() 89 | : undefined 90 | })) 91 | 92 | resolve(devWebpackConfig) 93 | } 94 | }) 95 | }) 96 | -------------------------------------------------------------------------------- /demo/build/webpack.prod.conf.js: -------------------------------------------------------------------------------- 1 | 'use strict' 2 | const path = require('path') 3 | const utils = require('./utils') 4 | const webpack = require('webpack') 5 | const config = require('../config') 6 | const merge = require('webpack-merge') 7 | const baseWebpackConfig = require('./webpack.base.conf') 8 | const CopyWebpackPlugin = require('copy-webpack-plugin') 9 | const HtmlWebpackPlugin = require('html-webpack-plugin') 10 | const ExtractTextPlugin = require('extract-text-webpack-plugin') 11 | const OptimizeCSSPlugin = require('optimize-css-assets-webpack-plugin') 12 | const UglifyJsPlugin = require('uglifyjs-webpack-plugin') 13 | 14 | const env = require('../config/prod.env') 15 | 16 | const webpackConfig = merge(baseWebpackConfig, { 17 | module: { 18 | rules: utils.styleLoaders({ 19 | sourceMap: config.build.productionSourceMap, 20 | extract: true, 21 | usePostCSS: true 22 | }) 23 | }, 24 | devtool: config.build.productionSourceMap ? config.build.devtool : false, 25 | output: { 26 | path: config.build.assetsRoot, 27 | filename: utils.assetsPath('js/[name].[chunkhash].js'), 28 | chunkFilename: utils.assetsPath('js/[id].[chunkhash].js') 29 | }, 30 | plugins: [ 31 | // http://vuejs.github.io/vue-loader/en/workflow/production.html 32 | new webpack.DefinePlugin({ 33 | 'process.env': env 34 | }), 35 | new UglifyJsPlugin({ 36 | uglifyOptions: { 37 | compress: { 38 | warnings: false 39 | } 40 | }, 41 | sourceMap: config.build.productionSourceMap, 42 | parallel: true 43 | }), 44 | // extract css into its own file 45 | new ExtractTextPlugin({ 46 | filename: utils.assetsPath('css/[name].[contenthash].css'), 47 | // Setting the following option to `false` will not extract CSS from codesplit chunks. 48 | // Their CSS will instead be inserted dynamically with style-loader when the codesplit chunk has been loaded by webpack. 49 | // It's currently set to `true` because we are seeing that sourcemaps are included in the codesplit bundle as well when it's `false`, 50 | // increasing file size: https://github.com/vuejs-templates/webpack/issues/1110 51 | allChunks: true, 52 | }), 53 | // Compress extracted CSS. We are using this plugin so that possible 54 | // duplicated CSS from different components can be deduped. 55 | new OptimizeCSSPlugin({ 56 | cssProcessorOptions: config.build.productionSourceMap 57 | ? { safe: true, map: { inline: false } } 58 | : { safe: true } 59 | }), 60 | // generate dist index.html with correct asset hash for caching. 61 | // you can customize output by editing /index.html 62 | // see https://github.com/ampedandwired/html-webpack-plugin 63 | new HtmlWebpackPlugin({ 64 | filename: config.build.index, 65 | template: 'index.html', 66 | inject: true, 67 | minify: { 68 | removeComments: true, 69 | collapseWhitespace: true, 70 | removeAttributeQuotes: true 71 | // more options: 72 | // https://github.com/kangax/html-minifier#options-quick-reference 73 | }, 74 | // necessary to consistently work with multiple chunks via CommonsChunkPlugin 75 | chunksSortMode: 'dependency' 76 | }), 77 | // keep module.id stable when vendor modules does not change 78 | new webpack.HashedModuleIdsPlugin(), 79 | // enable scope hoisting 80 | new webpack.optimize.ModuleConcatenationPlugin(), 81 | // split vendor js into its own file 82 | new webpack.optimize.CommonsChunkPlugin({ 83 | name: 'vendor', 84 | minChunks (module) { 85 | // any required modules inside node_modules are extracted to vendor 86 | return ( 87 | module.resource && 88 | /\.js$/.test(module.resource) && 89 | module.resource.indexOf( 90 | path.join(__dirname, '../node_modules') 91 | ) === 0 92 | ) 93 | } 94 | }), 95 | // extract webpack runtime and module manifest to its own file in order to 96 | // prevent vendor hash from being updated whenever app bundle is updated 97 | new webpack.optimize.CommonsChunkPlugin({ 98 | name: 'manifest', 99 | minChunks: Infinity 100 | }), 101 | // This instance extracts shared chunks from code splitted chunks and bundles them 102 | // in a separate chunk, similar to the vendor chunk 103 | // see: https://webpack.js.org/plugins/commons-chunk-plugin/#extra-async-commons-chunk 104 | new webpack.optimize.CommonsChunkPlugin({ 105 | name: 'app', 106 | async: 'vendor-async', 107 | children: true, 108 | minChunks: 3 109 | }), 110 | 111 | // copy custom static assets 112 | new CopyWebpackPlugin([ 113 | { 114 | from: path.resolve(__dirname, '../static'), 115 | to: config.build.assetsSubDirectory, 116 | ignore: ['.*'] 117 | } 118 | ]) 119 | ] 120 | }) 121 | 122 | if (config.build.productionGzip) { 123 | const CompressionWebpackPlugin = require('compression-webpack-plugin') 124 | 125 | webpackConfig.plugins.push( 126 | new CompressionWebpackPlugin({ 127 | asset: '[path].gz[query]', 128 | algorithm: 'gzip', 129 | test: new RegExp( 130 | '\\.(' + 131 | config.build.productionGzipExtensions.join('|') + 132 | ')$' 133 | ), 134 | threshold: 10240, 135 | minRatio: 0.8 136 | }) 137 | ) 138 | } 139 | 140 | if (config.build.bundleAnalyzerReport) { 141 | const BundleAnalyzerPlugin = require('webpack-bundle-analyzer').BundleAnalyzerPlugin 142 | webpackConfig.plugins.push(new BundleAnalyzerPlugin()) 143 | } 144 | 145 | module.exports = webpackConfig 146 | -------------------------------------------------------------------------------- /src/element.js: -------------------------------------------------------------------------------- 1 | 2 | 3 | export default class Element { 4 | constructor() { 5 | this.selectedLocation = null // 鼠标点击的位置 6 | } 7 | 8 | draw() { 9 | 10 | } 11 | 12 | getId() { 13 | return this.id; 14 | } 15 | 16 | setId(i) { 17 | this.id = i; 18 | } 19 | 20 | getFloatMenu() { 21 | return this.floatMenu; 22 | } 23 | 24 | setFloatMenu(m) { 25 | this.floatMenu = m; 26 | return this; 27 | } 28 | 29 | isFloatMenuVisible() { 30 | return this.floatMenuVisible; 31 | } 32 | 33 | setFloatMenuVisible(v) { 34 | this.floatMenuVisible = v; 35 | return this; 36 | } 37 | 38 | setX(x) { 39 | this.x = x; 40 | return this; 41 | } 42 | 43 | setY(y) { 44 | this.y = y; 45 | return this; 46 | } 47 | 48 | getX() { 49 | return this.x; 50 | } 51 | 52 | getY() { 53 | return this.y; 54 | } 55 | 56 | getLocation(x, y) { 57 | return { x: this.getX(), y: this.getY() }; 58 | } 59 | 60 | setLocation(x, y) { 61 | this.setX(x); 62 | this.setY(y); 63 | return this; 64 | } 65 | 66 | getWidth() { 67 | return this.width; 68 | } 69 | 70 | setWidth(width) { 71 | this.width = width; 72 | return this; 73 | } 74 | 75 | getHeight() { 76 | return this.height; 77 | } 78 | 79 | setHeight(height) { 80 | this.height = height; 81 | return this; 82 | } 83 | 84 | getSize() { 85 | return { width: this.getWidth(), height: this.getHeight() }; 86 | } 87 | 88 | setSize(width, height) { 89 | this.setWidth(width); 90 | this.setHeight(height); 91 | return this; 92 | } 93 | 94 | setBound(x, y, width, height) { 95 | this.setLocation(x, y); 96 | this.setSize(width, height); 97 | return this; 98 | } 99 | 100 | getBound() { 101 | return { 102 | left: this.getX(), top: this.getY(), 103 | right: this.getX() + this.getWidth(), bottom: this.getY() + this.getHeight() 104 | }; 105 | } 106 | 107 | isVisible() { 108 | return this.visible; 109 | } 110 | 111 | setVisible(v) { 112 | this.visible = v; 113 | return this; 114 | } 115 | 116 | isDragable() { 117 | return this.dragable; 118 | } 119 | 120 | setDragable(d) { 121 | this.dragable = d; 122 | return this; 123 | } 124 | 125 | isSelected() { 126 | return this.selected; 127 | } 128 | 129 | setSelected(s) { 130 | this.selected = s; 131 | return this; 132 | } 133 | 134 | isFocus() { 135 | return this.focus; 136 | } 137 | 138 | setFocus(f) { 139 | this.focus = f; 140 | return this; 141 | } 142 | 143 | onFocus() { 144 | this.setFocus(true); 145 | return this; 146 | } 147 | 148 | loseFocus() { 149 | this.setFocus(false); 150 | return this; 151 | } 152 | 153 | setTip(tip) { 154 | this.tip = tip; 155 | return this; 156 | } 157 | 158 | getTip() { 159 | return this.tip; 160 | } 161 | 162 | mousedown({ e, event }) { 163 | this.setSelected(true); 164 | this.mousedownX = e.x; 165 | this.mousedownY = e.y; 166 | this.selectedLocation = { x: this.getX(), y: this.getY() }; 167 | this.onMousedown(event) 168 | } 169 | 170 | onMouseselected() { 171 | // this.setSelected(true); 172 | // this.selectedLocation = { x: this.getX(), y: this.getY() }; 173 | } 174 | 175 | mouseselected(){ 176 | this.setSelected(true); 177 | this.selectedLocation = { x: this.getX(), y: this.getY() }; 178 | this.onMouseselected() 179 | } 180 | 181 | goBack(box) { 182 | } 183 | 184 | mouseup({ e, event }) { 185 | console.log('mouseup', 'ele') 186 | this.mouseupX = e.x; 187 | this.mouseupY = e.y; 188 | let x = e.x; 189 | let y = e.y; 190 | let box = e.context; 191 | 192 | if (this.gravitate) { 193 | for (let i = 0; i < box.links.length; i++) { 194 | let link = box.links[i]; 195 | if (this === link.nodeB) { 196 | let newNodeA = box.findCloserNode(this, this.gravitate); 197 | let gravitateMsg = { 198 | link: link, target: this, 199 | oldNode: this.lastParentNode, newNode: newNodeA 200 | }; 201 | if (newNodeA && newNodeA.layout && newNodeA.layout.auto == true) { 202 | box.layoutNode(newNodeA); 203 | } 204 | if (this.lastParentNode && this.lastParentNode.layout && this.lastParentNode.layout.auto == true) { 205 | box.layoutNode(this.lastParentNode); 206 | } 207 | box.publish('gravitate', { ...gravitateMsg}); 208 | break; 209 | } 210 | } 211 | } 212 | 213 | if (this.outContainer && this.isIndrag) { 214 | for (let j = 0; j < box.containers.length; j++) { 215 | let c = box.containers[j]; 216 | if (!this.inContainer(c)) continue; 217 | if (this.parentContainer !== c) continue; 218 | if (this.x + this.width < c.x || this.x > c.x + c.width || this.y + this.height < c.y || this.y > c.y + c.height) { 219 | this.parentContainer.remove(this); 220 | break; 221 | } 222 | } 223 | } 224 | 225 | if (this.inContainer && this.isOnMousedrag) { 226 | for (let j = 0; j < box.containers.length; j++) { 227 | let group = box.containers[j]; 228 | if (!this.inContainer(group)) continue; 229 | if (x > group.x && x < group.x + group.width && y > group.y && y < group.y + group.height) { 230 | if (this.parentContainer) { 231 | this.parentContainer.remove(this); 232 | } 233 | group.add(this); 234 | break; 235 | } 236 | } 237 | } 238 | if (this.layout && this.layout.auto == true) { 239 | box.layoutNode(this); 240 | } 241 | this.isOnMousedrag = false; 242 | this.onMouseup(event) 243 | } 244 | 245 | cancleSelected() { 246 | this.setSelected(false); 247 | this.selectedLocation = null; 248 | } 249 | 250 | onMousedown(event) { } 251 | onMouseup(event) { } 252 | onMouseover(event) { } 253 | onMouseout(event) { } 254 | onMousedrag(event) { } 255 | onContextmenu(event){ 256 | 257 | } 258 | contextmenu({event}){ 259 | this.onContextmenu(event) 260 | } 261 | mouseover({ e, event }) { 262 | this.isOnMousOver = true; 263 | this.isTipVisible = true; 264 | this.setFocus(true); 265 | this.onMouseover(event) 266 | } 267 | 268 | mouseout({ e, event }) { 269 | this.isOnMousOver = false; 270 | this.isTipVisible = false; 271 | this.setFocus(false); 272 | this.onMouseout(event) 273 | } 274 | 275 | mousedrag({ e, event }) { 276 | this.isOnMousedrag = true; 277 | let dx = e.dx; 278 | let dy = e.dy; 279 | let x = e.x; 280 | let y = e.y; 281 | 282 | let newX = this.selectedLocation.x + dx; 283 | let newY = this.selectedLocation.y + dy; 284 | this.setLocation(newX, newY); 285 | let box = e.context; 286 | 287 | if (this.gravitate) { 288 | for (let i = 0; i < box.links.length; i++) { 289 | let link = box.links[i]; 290 | if (this === link.nodeB) { 291 | let newNodeA = box.findCloserNode(this, this.gravitate); 292 | if (newNodeA != null && newNodeA !== link.nodeA) { 293 | if (this.lastParentNode == null) { 294 | this.lastParentNode = link.nodeA; 295 | } 296 | link.nodeA = newNodeA; 297 | break; 298 | } 299 | } 300 | } 301 | } 302 | 303 | if (this.inContainer) { 304 | for (let j = 0; j < box.containers.length; j++) { 305 | let group = box.containers[j]; 306 | if (!this.inContainer(group)) continue; 307 | if (x > group.x && x < group.x + group.width && y > group.y && y < group.y + group.height) { 308 | group.setFocus(true); 309 | } else { 310 | group.setFocus(false); 311 | } 312 | } 313 | } 314 | this.isIndrag = true; 315 | this.onMousedrag(event) 316 | } 317 | } 318 | -------------------------------------------------------------------------------- /src/stage.js: -------------------------------------------------------------------------------- 1 | import Util from './util' 2 | import { Node } from './node' 3 | import { Container } from './container' 4 | import { Link } from './link' 5 | 6 | export default class Stage { 7 | constructor(option) { 8 | this.name = option.name || ''; 9 | this.canvas = option.canvas; 10 | this.ctx = this.canvas.getContext("2d"); 11 | this.width = this.canvas.width; 12 | this.height = this.canvas.height; 13 | this.messageBus = new Util.MessageBus(); 14 | this.image = new Image(); 15 | this.image.src = option.imageSrc || ''; 16 | this.scale = 1 17 | this.isScale = option.isScale || false 18 | this.maxScale = 4 19 | this.minScale = 0.5 20 | this.init(); 21 | this.contextMenu = option.contextMenu || null 22 | } 23 | 24 | init() { 25 | this.ctx.shadowBlur = 5; 26 | this.ctx.shadowColor = 'rgba(0,0,0,0.5)'; 27 | this.ctx.shadowOffsetX = 3; 28 | this.ctx.shadowOffsetY = 6; 29 | this.ctx.scale(this.scale, this.scale) 30 | 31 | this.startDragMouseX = 0; 32 | this.startDragMouseY = 0; 33 | this.offset = this.canvas.getBoundingClientRect() 34 | // this.offset = canvas.offset(); 35 | this.isRangeSelectable = true; 36 | 37 | this.elements = []; 38 | this.containers = []; 39 | this.links = []; 40 | this.nodes = []; 41 | this.elementMap = {}; 42 | this.selectedElements = []; 43 | 44 | let box = this; 45 | this.canvas.onmousedown = function (event) { 46 | box.isMousedown = true; 47 | box.canvas.style.cursor = 'move' 48 | box.mousedown(event); 49 | event.preventDefault(); 50 | }; 51 | this.canvas.onresize = function (event) { 52 | box.offset = box.canvas.getBoundingClientRect() 53 | } 54 | this.canvas.onmousemove = function (event) { 55 | box.mousemove(event); 56 | }; 57 | this.canvas.onmouseup = function (event) { 58 | box.isMousedown = false; 59 | box.canvas.style.cursor = 'default' 60 | box.mouseup(event); 61 | }; 62 | if (this.isScale) { 63 | this.canvas.onmousewheel = function (event) { 64 | event = event || window.event; 65 | box.mousewheel(event) 66 | event.preventDefault(); 67 | box.updateView() 68 | } 69 | } 70 | if (this.contextMenu) { 71 | this.canvas.oncontextmenu = function (event) { 72 | event = event || window.event; 73 | box.contextmenu(event) 74 | event.preventDefault(); 75 | return false; 76 | } 77 | } 78 | try {// IE !! 79 | window.addEventListener('keydown', function (e) { 80 | box.keydown(e); 81 | e.preventDefault(); 82 | }, true); 83 | window.addEventListener('keyup', function (e) { 84 | box.keyup(e); 85 | e.preventDefault(); 86 | }, true); 87 | } catch (e) { } 88 | 89 | setTimeout(() => { 90 | box.offset = box.canvas.getBoundingClientRect(); 91 | box.updateView() 92 | }, 300); 93 | } 94 | 95 | attachMousewheel() { 96 | let box = this 97 | this.canvas.onmousewheel = function (event) { 98 | event = event || window.event; 99 | box.mousewheel(event) 100 | event.preventDefault(); 101 | box.updateView() 102 | } 103 | this.isScale = true 104 | } 105 | 106 | cancleMousewheel() { 107 | this.canvas.onmousewheel = null 108 | this.isScale = false 109 | } 110 | 111 | getElementByXY(x, y) { 112 | let e = null; 113 | for (let i = this.nodes.length - 1; i >= 0; i--) { 114 | let node = this.nodes[i]; 115 | if (x > node.x && x < node.x + node.width && y > node.y && y < node.y + node.height) { 116 | e = node; 117 | break; 118 | } 119 | } 120 | if (!e) { 121 | for (let i = this.containers.length - 1; i >= 0; i--) { 122 | let group = this.containers[i]; 123 | if (x > group.x && x < group.x + group.width && y > group.y && y < group.y + group.height) { 124 | e = group; 125 | break; 126 | } 127 | } 128 | } 129 | return e; 130 | } 131 | 132 | getElementByName(name) { 133 | for (let i = this.nodes.length - 1; i >= 0; i--) { 134 | if (this.nodes[i].getName() == name) { 135 | return this.nodes[i]; 136 | } 137 | } 138 | return null; 139 | } 140 | 141 | findCloserNode(node, cond) { 142 | let min = { distance: Number.MAX_VALUE, node: null }; 143 | for (let i = this.nodes.length - 1; i >= 0; i--) { 144 | let typeNode = this.nodes[i]; 145 | if (typeNode === node) continue; 146 | if (cond(typeNode) == true) { 147 | let dist = Util.getDistance(node, typeNode); 148 | if (dist < min.distance) { 149 | min.node = typeNode; 150 | min.distance = dist; 151 | } 152 | } 153 | } 154 | return min.node; 155 | } 156 | 157 | cancleAllSelected() { 158 | this.selectedElements.forEach(item => item.cancleSelected()) 159 | this.selectedElements = []; 160 | }; 161 | 162 | /** 163 | * 鼠标滚轮滚动, 缩放 164 | * @param {Event} event 165 | */ 166 | mousewheel(event) { 167 | let scale = 1; 168 | if (event.wheelDelta > 0) { 169 | if (this.scale >= this.maxScale) { 170 | return 171 | } 172 | scale = 2; 173 | 174 | } else { 175 | if (this.scale <= this.minScale) { 176 | return 177 | } 178 | scale = 0.5 179 | } 180 | this.scale *= scale 181 | const xy = Util.getXY(this, event) 182 | const newXy = { x: xy.x * 2, y: xy.y * 2 } 183 | this.links.forEach(link => link.style.lineWidth *= scale) 184 | this.containers.forEach(container => { 185 | container.width *= scale 186 | container.height *= scale 187 | container.x = container.x * scale 188 | container.y = container.y * scale 189 | }) 190 | this.nodes.forEach(node => { 191 | node.width *= scale 192 | node.height *= scale 193 | node.x = node.x * scale 194 | node.y = node.y * scale 195 | }) 196 | } 197 | 198 | mousedown(event) { 199 | let xy = Util.getXY(this, event); 200 | let x = xy.x; 201 | let y = xy.y; 202 | 203 | let selectedNode = this.getElementByXY(x, y); 204 | if (selectedNode && selectedNode != null) { 205 | selectedNode.mousedown({ e: { x: x, y: y, context: this }, event }); 206 | this.currElement = selectedNode; 207 | } else if (this.currElement && this.currElement != null) { 208 | this.currElement.cancleSelected(); 209 | this.currElement = null; 210 | } 211 | 212 | this.startDragMouseX = x; 213 | this.startDragMouseY = y; 214 | 215 | if (this.currElement) { 216 | if (this.selectedElements.indexOf(this.currElement) == -1) { 217 | this.cancleAllSelected(); 218 | this.selectedElements.push(this.currElement); 219 | } 220 | } else { 221 | this.cancleAllSelected(); 222 | } 223 | 224 | for (let i = 0; i < this.selectedElements.length; i++) { 225 | let node = this.selectedElements[i]; 226 | node.selectedLocation = { x: node.x, y: node.y }; 227 | } 228 | 229 | if (!this.currElement || this.currElement == null) { 230 | console.log('mousedown') 231 | this.nodes.forEach(node => node.selectedLocation = { x: node.getX(), y: node.getY() }) 232 | } 233 | this.isOnMouseDown = true; 234 | this.publish('mousedown', { target: this.currElement, x: x, y: y, context: this }); 235 | } 236 | 237 | mousemove(event) { 238 | let xy = Util.getXY(this, event); 239 | let x = xy.x; 240 | let y = xy.y; 241 | let dx = (x - this.startDragMouseX); 242 | let dy = (y - this.startDragMouseY); 243 | this.publish('mousemove', { target: this.currElement, x: x, y: y, dx: dx, dy: dy, context: this }); 244 | 245 | //if(this.currElement && !this.currElement.isDragable()) return; 246 | 247 | this.updateView(); 248 | for (let i = this.nodes.length - 1; i >= 0; i--) { 249 | let node = this.nodes[i]; 250 | if (node.x + node.width < 0 || node.x > this.canvas.width) continue; 251 | 252 | if (x > node.x && x < node.x + node.width && y > node.y && y < node.y + node.height) { 253 | node.mouseover({ e: { x: x, y: y, dx: dx, dy: dy, context: this }, event }); 254 | this.publish('mouseover', { target: node, x: x, y: y, dx: dx, dy: dy, context: this }); 255 | } else { 256 | if (node.isOnMousOver) { 257 | node.mouseout({ e: { x: x, y: y, dx: dx, dy: dy, context: this }, event }); 258 | this.publish('mouseout', { target: node, x: x, y: y, dx: dx, dy: dy, context: this }); 259 | } 260 | } 261 | } 262 | if (this.currElement && this.isOnMouseDown && this.currElement.isDragable()) { 263 | this.selectedElements.forEach(node => node.mousedrag({ e: { x: x, y: y, dx: dx, dy: dy, context: this }, event })) 264 | // for (let i = 0; i < this.selectedElements.length; i++) { 265 | // let node = this.selectedElements[i]; 266 | // node.mousedrag({ x: x, y: y, dx: dx, dy: dy, context: this }); 267 | // } 268 | this.publish('mousedrag', { target: this.currElement, x: x, y: y }); 269 | } else if (this.isOnMouseDown && this.isRangeSelectable && !this.isScale) { 270 | let startx = x >= this.startDragMouseX ? this.startDragMouseX : x; 271 | let starty = y >= this.startDragMouseY ? this.startDragMouseY : y; 272 | let width = Math.abs(x - this.startDragMouseX); 273 | let height = Math.abs(y - this.startDragMouseY); 274 | 275 | this.ctx.beginPath(); 276 | this.ctx.fillStyle = 'rgba(168,202,236,0.5)'; 277 | this.ctx.fillRect(startx, starty, width, height); 278 | this.ctx.closePath(); 279 | 280 | this.nodes.forEach(node => { 281 | if (node.x + node.width < 0 || node.x > this.canvas.width) return; 282 | 283 | if (node.x > startx && node.x + node.width < startx + width) { 284 | if (node.y > starty && node.y + node.height < starty + height) { 285 | node.mouseselected({ e: { x: x, y: y, dx: dx, dy: dy, context: this }, event }); 286 | this.selectedElements.push(node); 287 | } 288 | } else { 289 | node.cancleSelected(); 290 | } 291 | }) 292 | } else if (this.isOnMouseDown && this.isScale) { 293 | this.nodes.forEach(node => node.mousedrag({ e: { x: x, y: y, dx: dx, dy: dy, context: this }, event })) 294 | this.publish('mousedrag', { target: this.currElement, x: x, y: y }); 295 | } 296 | } 297 | 298 | mouseup(event) { 299 | let xy = Util.getXY(this, event); 300 | let x = xy.x; 301 | let y = xy.y; 302 | let dx = (x - this.startDragMouseX); 303 | let dy = (y - this.startDragMouseY); 304 | 305 | this.publish('mouseup', { target: this.currElement, x: x, y: y, dx: dx, dy: dy, context: this }); 306 | this.startDragMouseX = null; 307 | console.log('mouseup', 'stage') 308 | if (this.currElement) { 309 | this.currElement.mouseup({ e: { x: x, y: y, context: this, dx: dx, dy: dy }, event }); 310 | } 311 | this.updateView(); 312 | this.isOnMouseDown = false; 313 | } 314 | 315 | keydown(e) { 316 | let keyID = e.keyCode ? e.keyCode : e.which; 317 | this.publish('keydown', keyID); 318 | // this.updateView(); 319 | // return; 320 | 321 | if (keyID === 17) { // Ctrl 322 | } 323 | if (keyID === 18) {// Alt 324 | } 325 | if (keyID === 16) { // Shift 326 | } 327 | if (keyID === 27) { // Esc 328 | this.cancleAllSelected(); 329 | this.currElement = null; 330 | } 331 | if (keyID === 38 || keyID === 87) { // up arrow and W 332 | if (this.currElement) { 333 | this.currElement.y -= 5; 334 | } 335 | } 336 | if (keyID === 39 || keyID === 68) { // right arrow and D 337 | if (this.currElement) { 338 | this.currElement.x += 5; 339 | } 340 | } 341 | if (keyID === 40 || keyID === 83) { // down arrow and S 342 | if (this.currElement) { 343 | this.currElement.y += 5; 344 | } 345 | } 346 | if (keyID === 37 || keyID === 65) { // left arrow and A 347 | if (this.currElement) { 348 | this.currElement.x -= 5; 349 | } 350 | } 351 | this.updateView(); 352 | } 353 | 354 | keyup(e) { 355 | let keyID = e.keyCode ? e.keyCode : e.which; 356 | this.publish('keyup', keyID); 357 | this.updateView(); 358 | } 359 | 360 | contextmenu(event) { 361 | this.selectedElements.forEach( node => node.contextmenu({event})) 362 | } 363 | subscribe(topic, action) { 364 | this.messageBus.subscribe(topic, action); 365 | return this; 366 | } 367 | 368 | publish(topic, msg) { 369 | this.messageBus.publish(topic, msg); 370 | return this; 371 | } 372 | 373 | removeElementById(id) { 374 | for (let i = 0; i < this.elements.length; i++) { 375 | if (this.elements[i].id == id) { 376 | this.remove(i); 377 | break; 378 | } 379 | } 380 | } 381 | 382 | remove(e) { 383 | this.elements = this.elements.del(e); 384 | this.containers = this.containers.del(e); 385 | this.links = this.links.del(e); 386 | this.nodes = this.nodes.del(e); 387 | this.elementMap[e.id] = e; 388 | } 389 | 390 | addElement(e) { 391 | return this.add(e); 392 | } 393 | 394 | add(e) { 395 | if (this.elementMap[e.id] != null) { 396 | return; 397 | } 398 | if (!e.id) e.id = (new Date()).getTime(); 399 | if (!e.z) e.z = this.elements.length; 400 | this.elements.push(e); 401 | if (e instanceof Container) { 402 | this.containers.push(e); 403 | } else if (e instanceof Link) { 404 | this.links.push(e); 405 | } else if (e instanceof Node) { 406 | this.nodes.push(e); 407 | } 408 | this.elementMap[e.id] = e; 409 | } 410 | 411 | clear() { 412 | this.elements = []; 413 | this.links = []; 414 | this.nodes = []; 415 | this.containers = []; 416 | this.elementMap = {}; 417 | } 418 | 419 | getChilds(node) { 420 | let result = []; 421 | for (let i = 0; i < this.links.length; i++) { 422 | if (this.links[i].nodeA === node) { 423 | result.push(this.links[i].nodeB); 424 | } 425 | } 426 | return result; 427 | } 428 | 429 | getNodesBound(nodes) { 430 | let bound = { x: 10000000, y: 1000000, width: 0, height: 0 }; 431 | if (nodes.length > 0) { 432 | let minX = 10000000; 433 | let maxX = -10000000; 434 | let minY = 10000000; 435 | let maxY = -10000000; 436 | let width = maxX - minX; 437 | let height = maxY - minY; 438 | for (let i = 0; i < nodes.length; i++) { 439 | let item = nodes[i]; 440 | if (item.x <= minX) { 441 | minX = item.x; 442 | } 443 | if (item.x >= maxX) { 444 | maxX = item.x; 445 | } 446 | if (item.y <= minY) { 447 | minY = item.y; 448 | } 449 | if (item.y >= maxY) { 450 | maxY = item.y; 451 | } 452 | width = maxX - minX + item.width; 453 | height = maxY - minY + item.height; 454 | } 455 | 456 | bound.x = minX; 457 | bound.y = minY; 458 | bound.width = width; 459 | bound.height = height; 460 | return bound; 461 | } 462 | return null; 463 | } 464 | 465 | isAllChildIsEndpoint(node) { 466 | let childs = this.getChilds(node); 467 | for (let i = 0; i < childs.length; i++) { 468 | let grandsons = this.getChilds(childs[i]); 469 | if (grandsons.length > 0) return false; 470 | } 471 | return true; 472 | } 473 | 474 | getBoundRecursion(node) { 475 | let childs = this.getChilds(node); 476 | if (childs.length == 0) return node.getBound(); 477 | return this.getNodesBound(childs); 478 | } 479 | 480 | layoutNode(node) { 481 | let childs = this.getChilds(node); 482 | if (childs.length == 0) return node.getBound(); 483 | 484 | this.adjustPosition(node); 485 | if (this.isAllChildIsEndpoint(node)) { 486 | return null; 487 | } 488 | for (let i = 0; i < childs.length; i++) { 489 | this.layoutNode(childs[i]); 490 | } 491 | return null; 492 | } 493 | 494 | adjustPosition(node) { 495 | let childs = this.getChilds(node); 496 | let layout = node.layout; 497 | let type = layout.type; 498 | let points = null; 499 | if (type == 'star') { 500 | points = JTopo.Layout.getStarPositions(node.x, node.y, childs.length, node.layout.radius, 501 | node.layout.beginDegree, node.layout.endDegree); 502 | } else if (type == 'tree') { 503 | points = JTopo.Layout.getTreePositions(node.x, node.y, childs.length, layout.width, 504 | layout.height, layout.direction); 505 | } 506 | for (let i = 0; i < childs.length; i++) { 507 | childs[i].setLocation(points[i].x, points[i].y); 508 | } 509 | } 510 | 511 | getParents(node) { 512 | let result = []; 513 | for (let i = 0; i < this.links.length; i++) { 514 | if (this.links[i].nodeB === node) { 515 | result.push(this.links[i].nodeA); 516 | } 517 | } 518 | return result; 519 | } 520 | 521 | updateView() { 522 | this.ctx.clearRect(0, 0, this.canvas.width, this.canvas.height); 523 | // this.ctx.scale(this.scareX, this.scareY); 524 | if (this.image != null) { 525 | this.ctx.drawImage(this.image, 0, 0, this.width, this.height); 526 | } 527 | 528 | for (let i = 0; i < this.links.length; i++) { 529 | let link = this.links[i]; 530 | if (link.nodeA.x + link.nodeA.width < 0 || link.nodeA.x > this.canvas.width) continue; 531 | if (link.nodeB.x + link.nodeA.width < 0 || link.nodeB.x > this.canvas.width) continue; 532 | 533 | link.draw(this.ctx); 534 | } 535 | 536 | for (let i = 0; i < this.containers.length; i++) { 537 | let c = this.containers[i]; 538 | if (c.x + c.width < 0 || c.x > this.canvas.width) continue; 539 | 540 | this.containers[i].draw(this.ctx); 541 | } 542 | for (let i = 0; i < this.nodes.length; i++) { 543 | if (this.nodes[i].x + this.nodes[i].width < 0 || this.nodes[i].x > this.canvas.width) continue; 544 | this.nodes[i].draw(this.ctx); 545 | } 546 | } 547 | } 548 | -------------------------------------------------------------------------------- /yarn.lock: -------------------------------------------------------------------------------- 1 | # THIS IS AN AUTOGENERATED FILE. DO NOT EDIT THIS FILE DIRECTLY. 2 | # yarn lockfile v1 3 | 4 | 5 | abbrev@1: 6 | version "1.1.1" 7 | resolved "http://registry.npm.taobao.org/abbrev/download/abbrev-1.1.1.tgz#f8f2c887ad10bf67f634f005b6987fed3179aac8" 8 | 9 | ansi-regex@^2.0.0: 10 | version "2.1.1" 11 | resolved "http://registry.npm.taobao.org/ansi-regex/download/ansi-regex-2.1.1.tgz#c3b33ab5ee360d86e0e628f0468ae7ef27d654df" 12 | 13 | ansi-styles@^2.2.1: 14 | version "2.2.1" 15 | resolved "http://registry.npm.taobao.org/ansi-styles/download/ansi-styles-2.2.1.tgz#b432dd3358b634cf75e1e4664368240533c1ddbe" 16 | 17 | anymatch@^1.3.0: 18 | version "1.3.2" 19 | resolved "http://registry.npm.taobao.org/anymatch/download/anymatch-1.3.2.tgz#553dcb8f91e3c889845dfdba34c77721b90b9d7a" 20 | dependencies: 21 | micromatch "^2.1.5" 22 | normalize-path "^2.0.0" 23 | 24 | aproba@^1.0.3: 25 | version "1.2.0" 26 | resolved "http://registry.npm.taobao.org/aproba/download/aproba-1.2.0.tgz#6802e6264efd18c790a1b0d517f0f2627bf2c94a" 27 | 28 | are-we-there-yet@~1.1.2: 29 | version "1.1.4" 30 | resolved "http://registry.npm.taobao.org/are-we-there-yet/download/are-we-there-yet-1.1.4.tgz#bb5dca382bb94f05e15194373d16fd3ba1ca110d" 31 | dependencies: 32 | delegates "^1.0.0" 33 | readable-stream "^2.0.6" 34 | 35 | arr-diff@^2.0.0: 36 | version "2.0.0" 37 | resolved "http://registry.npm.taobao.org/arr-diff/download/arr-diff-2.0.0.tgz#8f3b827f955a8bd669697e4a4256ac3ceae356cf" 38 | dependencies: 39 | arr-flatten "^1.0.1" 40 | 41 | arr-flatten@^1.0.1: 42 | version "1.1.0" 43 | resolved "http://registry.npm.taobao.org/arr-flatten/download/arr-flatten-1.1.0.tgz#36048bbff4e7b47e136644316c99669ea5ae91f1" 44 | 45 | array-unique@^0.2.1: 46 | version "0.2.1" 47 | resolved "http://registry.npm.taobao.org/array-unique/download/array-unique-0.2.1.tgz#a1d97ccafcbc2625cc70fadceb36a50c58b01a53" 48 | 49 | async-each@^1.0.0: 50 | version "1.0.1" 51 | resolved "http://registry.npm.taobao.org/async-each/download/async-each-1.0.1.tgz#19d386a1d9edc6e7c1c85d388aedbcc56d33602d" 52 | 53 | babel-cli@^6.24.1: 54 | version "6.26.0" 55 | resolved "http://registry.npm.taobao.org/babel-cli/download/babel-cli-6.26.0.tgz#502ab54874d7db88ad00b887a06383ce03d002f1" 56 | dependencies: 57 | babel-core "^6.26.0" 58 | babel-polyfill "^6.26.0" 59 | babel-register "^6.26.0" 60 | babel-runtime "^6.26.0" 61 | commander "^2.11.0" 62 | convert-source-map "^1.5.0" 63 | fs-readdir-recursive "^1.0.0" 64 | glob "^7.1.2" 65 | lodash "^4.17.4" 66 | output-file-sync "^1.1.2" 67 | path-is-absolute "^1.0.1" 68 | slash "^1.0.0" 69 | source-map "^0.5.6" 70 | v8flags "^2.1.1" 71 | optionalDependencies: 72 | chokidar "^1.6.1" 73 | 74 | babel-code-frame@^6.26.0: 75 | version "6.26.0" 76 | resolved "http://registry.npm.taobao.org/babel-code-frame/download/babel-code-frame-6.26.0.tgz#63fd43f7dc1e3bb7ce35947db8fe369a3f58c74b" 77 | dependencies: 78 | chalk "^1.1.3" 79 | esutils "^2.0.2" 80 | js-tokens "^3.0.2" 81 | 82 | babel-core@^6.25.0, babel-core@^6.26.0: 83 | version "6.26.3" 84 | resolved "http://registry.npm.taobao.org/babel-core/download/babel-core-6.26.3.tgz#b2e2f09e342d0f0c88e2f02e067794125e75c207" 85 | dependencies: 86 | babel-code-frame "^6.26.0" 87 | babel-generator "^6.26.0" 88 | babel-helpers "^6.24.1" 89 | babel-messages "^6.23.0" 90 | babel-register "^6.26.0" 91 | babel-runtime "^6.26.0" 92 | babel-template "^6.26.0" 93 | babel-traverse "^6.26.0" 94 | babel-types "^6.26.0" 95 | babylon "^6.18.0" 96 | convert-source-map "^1.5.1" 97 | debug "^2.6.9" 98 | json5 "^0.5.1" 99 | lodash "^4.17.4" 100 | minimatch "^3.0.4" 101 | path-is-absolute "^1.0.1" 102 | private "^0.1.8" 103 | slash "^1.0.0" 104 | source-map "^0.5.7" 105 | 106 | babel-generator@^6.26.0: 107 | version "6.26.1" 108 | resolved "http://registry.npm.taobao.org/babel-generator/download/babel-generator-6.26.1.tgz#1844408d3b8f0d35a404ea7ac180f087a601bd90" 109 | dependencies: 110 | babel-messages "^6.23.0" 111 | babel-runtime "^6.26.0" 112 | babel-types "^6.26.0" 113 | detect-indent "^4.0.0" 114 | jsesc "^1.3.0" 115 | lodash "^4.17.4" 116 | source-map "^0.5.7" 117 | trim-right "^1.0.1" 118 | 119 | babel-helper-builder-binary-assignment-operator-visitor@^6.24.1: 120 | version "6.24.1" 121 | resolved "http://registry.npm.taobao.org/babel-helper-builder-binary-assignment-operator-visitor/download/babel-helper-builder-binary-assignment-operator-visitor-6.24.1.tgz#cce4517ada356f4220bcae8a02c2b346f9a56664" 122 | dependencies: 123 | babel-helper-explode-assignable-expression "^6.24.1" 124 | babel-runtime "^6.22.0" 125 | babel-types "^6.24.1" 126 | 127 | babel-helper-call-delegate@^6.24.1: 128 | version "6.24.1" 129 | resolved "http://registry.npm.taobao.org/babel-helper-call-delegate/download/babel-helper-call-delegate-6.24.1.tgz#ece6aacddc76e41c3461f88bfc575bd0daa2df8d" 130 | dependencies: 131 | babel-helper-hoist-variables "^6.24.1" 132 | babel-runtime "^6.22.0" 133 | babel-traverse "^6.24.1" 134 | babel-types "^6.24.1" 135 | 136 | babel-helper-define-map@^6.24.1: 137 | version "6.26.0" 138 | resolved "http://registry.npm.taobao.org/babel-helper-define-map/download/babel-helper-define-map-6.26.0.tgz#a5f56dab41a25f97ecb498c7ebaca9819f95be5f" 139 | dependencies: 140 | babel-helper-function-name "^6.24.1" 141 | babel-runtime "^6.26.0" 142 | babel-types "^6.26.0" 143 | lodash "^4.17.4" 144 | 145 | babel-helper-explode-assignable-expression@^6.24.1: 146 | version "6.24.1" 147 | resolved "http://registry.npm.taobao.org/babel-helper-explode-assignable-expression/download/babel-helper-explode-assignable-expression-6.24.1.tgz#f25b82cf7dc10433c55f70592d5746400ac22caa" 148 | dependencies: 149 | babel-runtime "^6.22.0" 150 | babel-traverse "^6.24.1" 151 | babel-types "^6.24.1" 152 | 153 | babel-helper-function-name@^6.24.1: 154 | version "6.24.1" 155 | resolved "http://registry.npm.taobao.org/babel-helper-function-name/download/babel-helper-function-name-6.24.1.tgz#d3475b8c03ed98242a25b48351ab18399d3580a9" 156 | dependencies: 157 | babel-helper-get-function-arity "^6.24.1" 158 | babel-runtime "^6.22.0" 159 | babel-template "^6.24.1" 160 | babel-traverse "^6.24.1" 161 | babel-types "^6.24.1" 162 | 163 | babel-helper-get-function-arity@^6.24.1: 164 | version "6.24.1" 165 | resolved "http://registry.npm.taobao.org/babel-helper-get-function-arity/download/babel-helper-get-function-arity-6.24.1.tgz#8f7782aa93407c41d3aa50908f89b031b1b6853d" 166 | dependencies: 167 | babel-runtime "^6.22.0" 168 | babel-types "^6.24.1" 169 | 170 | babel-helper-hoist-variables@^6.24.1: 171 | version "6.24.1" 172 | resolved "http://registry.npm.taobao.org/babel-helper-hoist-variables/download/babel-helper-hoist-variables-6.24.1.tgz#1ecb27689c9d25513eadbc9914a73f5408be7a76" 173 | dependencies: 174 | babel-runtime "^6.22.0" 175 | babel-types "^6.24.1" 176 | 177 | babel-helper-optimise-call-expression@^6.24.1: 178 | version "6.24.1" 179 | resolved "http://registry.npm.taobao.org/babel-helper-optimise-call-expression/download/babel-helper-optimise-call-expression-6.24.1.tgz#f7a13427ba9f73f8f4fa993c54a97882d1244257" 180 | dependencies: 181 | babel-runtime "^6.22.0" 182 | babel-types "^6.24.1" 183 | 184 | babel-helper-regex@^6.24.1: 185 | version "6.26.0" 186 | resolved "http://registry.npm.taobao.org/babel-helper-regex/download/babel-helper-regex-6.26.0.tgz#325c59f902f82f24b74faceed0363954f6495e72" 187 | dependencies: 188 | babel-runtime "^6.26.0" 189 | babel-types "^6.26.0" 190 | lodash "^4.17.4" 191 | 192 | babel-helper-remap-async-to-generator@^6.24.1: 193 | version "6.24.1" 194 | resolved "http://registry.npm.taobao.org/babel-helper-remap-async-to-generator/download/babel-helper-remap-async-to-generator-6.24.1.tgz#5ec581827ad723fecdd381f1c928390676e4551b" 195 | dependencies: 196 | babel-helper-function-name "^6.24.1" 197 | babel-runtime "^6.22.0" 198 | babel-template "^6.24.1" 199 | babel-traverse "^6.24.1" 200 | babel-types "^6.24.1" 201 | 202 | babel-helper-replace-supers@^6.24.1: 203 | version "6.24.1" 204 | resolved "http://registry.npm.taobao.org/babel-helper-replace-supers/download/babel-helper-replace-supers-6.24.1.tgz#bf6dbfe43938d17369a213ca8a8bf74b6a90ab1a" 205 | dependencies: 206 | babel-helper-optimise-call-expression "^6.24.1" 207 | babel-messages "^6.23.0" 208 | babel-runtime "^6.22.0" 209 | babel-template "^6.24.1" 210 | babel-traverse "^6.24.1" 211 | babel-types "^6.24.1" 212 | 213 | babel-helpers@^6.24.1: 214 | version "6.24.1" 215 | resolved "http://registry.npm.taobao.org/babel-helpers/download/babel-helpers-6.24.1.tgz#3471de9caec388e5c850e597e58a26ddf37602b2" 216 | dependencies: 217 | babel-runtime "^6.22.0" 218 | babel-template "^6.24.1" 219 | 220 | babel-messages@^6.23.0: 221 | version "6.23.0" 222 | resolved "http://registry.npm.taobao.org/babel-messages/download/babel-messages-6.23.0.tgz#f3cdf4703858035b2a2951c6ec5edf6c62f2630e" 223 | dependencies: 224 | babel-runtime "^6.22.0" 225 | 226 | babel-plugin-check-es2015-constants@^6.22.0: 227 | version "6.22.0" 228 | resolved "http://registry.npm.taobao.org/babel-plugin-check-es2015-constants/download/babel-plugin-check-es2015-constants-6.22.0.tgz#35157b101426fd2ffd3da3f75c7d1e91835bbf8a" 229 | dependencies: 230 | babel-runtime "^6.22.0" 231 | 232 | babel-plugin-syntax-async-functions@^6.8.0: 233 | version "6.13.0" 234 | resolved "http://registry.npm.taobao.org/babel-plugin-syntax-async-functions/download/babel-plugin-syntax-async-functions-6.13.0.tgz#cad9cad1191b5ad634bf30ae0872391e0647be95" 235 | 236 | babel-plugin-syntax-class-properties@^6.8.0: 237 | version "6.13.0" 238 | resolved "http://registry.npm.taobao.org/babel-plugin-syntax-class-properties/download/babel-plugin-syntax-class-properties-6.13.0.tgz#d7eb23b79a317f8543962c505b827c7d6cac27de" 239 | 240 | babel-plugin-syntax-decorators@^6.1.18: 241 | version "6.13.0" 242 | resolved "http://registry.npm.taobao.org/babel-plugin-syntax-decorators/download/babel-plugin-syntax-decorators-6.13.0.tgz#312563b4dbde3cc806cee3e416cceeaddd11ac0b" 243 | 244 | babel-plugin-syntax-exponentiation-operator@^6.8.0: 245 | version "6.13.0" 246 | resolved "http://registry.npm.taobao.org/babel-plugin-syntax-exponentiation-operator/download/babel-plugin-syntax-exponentiation-operator-6.13.0.tgz#9ee7e8337290da95288201a6a57f4170317830de" 247 | 248 | babel-plugin-syntax-object-rest-spread@^6.8.0: 249 | version "6.13.0" 250 | resolved "http://registry.npm.taobao.org/babel-plugin-syntax-object-rest-spread/download/babel-plugin-syntax-object-rest-spread-6.13.0.tgz#fd6536f2bce13836ffa3a5458c4903a597bb3bf5" 251 | 252 | babel-plugin-syntax-trailing-function-commas@^6.22.0: 253 | version "6.22.0" 254 | resolved "http://registry.npm.taobao.org/babel-plugin-syntax-trailing-function-commas/download/babel-plugin-syntax-trailing-function-commas-6.22.0.tgz#ba0360937f8d06e40180a43fe0d5616fff532cf3" 255 | 256 | babel-plugin-transform-async-to-generator@^6.22.0: 257 | version "6.24.1" 258 | resolved "http://registry.npm.taobao.org/babel-plugin-transform-async-to-generator/download/babel-plugin-transform-async-to-generator-6.24.1.tgz#6536e378aff6cb1d5517ac0e40eb3e9fc8d08761" 259 | dependencies: 260 | babel-helper-remap-async-to-generator "^6.24.1" 261 | babel-plugin-syntax-async-functions "^6.8.0" 262 | babel-runtime "^6.22.0" 263 | 264 | babel-plugin-transform-class-properties@^6.24.1: 265 | version "6.24.1" 266 | resolved "http://registry.npm.taobao.org/babel-plugin-transform-class-properties/download/babel-plugin-transform-class-properties-6.24.1.tgz#6a79763ea61d33d36f37b611aa9def81a81b46ac" 267 | dependencies: 268 | babel-helper-function-name "^6.24.1" 269 | babel-plugin-syntax-class-properties "^6.8.0" 270 | babel-runtime "^6.22.0" 271 | babel-template "^6.24.1" 272 | 273 | babel-plugin-transform-decorators-legacy@^1.3.4: 274 | version "1.3.4" 275 | resolved "http://registry.npm.taobao.org/babel-plugin-transform-decorators-legacy/download/babel-plugin-transform-decorators-legacy-1.3.4.tgz#741b58f6c5bce9e6027e0882d9c994f04f366925" 276 | dependencies: 277 | babel-plugin-syntax-decorators "^6.1.18" 278 | babel-runtime "^6.2.0" 279 | babel-template "^6.3.0" 280 | 281 | babel-plugin-transform-es2015-arrow-functions@^6.22.0: 282 | version "6.22.0" 283 | resolved "http://registry.npm.taobao.org/babel-plugin-transform-es2015-arrow-functions/download/babel-plugin-transform-es2015-arrow-functions-6.22.0.tgz#452692cb711d5f79dc7f85e440ce41b9f244d221" 284 | dependencies: 285 | babel-runtime "^6.22.0" 286 | 287 | babel-plugin-transform-es2015-block-scoped-functions@^6.22.0: 288 | version "6.22.0" 289 | resolved "http://registry.npm.taobao.org/babel-plugin-transform-es2015-block-scoped-functions/download/babel-plugin-transform-es2015-block-scoped-functions-6.22.0.tgz#bbc51b49f964d70cb8d8e0b94e820246ce3a6141" 290 | dependencies: 291 | babel-runtime "^6.22.0" 292 | 293 | babel-plugin-transform-es2015-block-scoping@^6.23.0: 294 | version "6.26.0" 295 | resolved "http://registry.npm.taobao.org/babel-plugin-transform-es2015-block-scoping/download/babel-plugin-transform-es2015-block-scoping-6.26.0.tgz#d70f5299c1308d05c12f463813b0a09e73b1895f" 296 | dependencies: 297 | babel-runtime "^6.26.0" 298 | babel-template "^6.26.0" 299 | babel-traverse "^6.26.0" 300 | babel-types "^6.26.0" 301 | lodash "^4.17.4" 302 | 303 | babel-plugin-transform-es2015-classes@^6.23.0: 304 | version "6.24.1" 305 | resolved "http://registry.npm.taobao.org/babel-plugin-transform-es2015-classes/download/babel-plugin-transform-es2015-classes-6.24.1.tgz#5a4c58a50c9c9461e564b4b2a3bfabc97a2584db" 306 | dependencies: 307 | babel-helper-define-map "^6.24.1" 308 | babel-helper-function-name "^6.24.1" 309 | babel-helper-optimise-call-expression "^6.24.1" 310 | babel-helper-replace-supers "^6.24.1" 311 | babel-messages "^6.23.0" 312 | babel-runtime "^6.22.0" 313 | babel-template "^6.24.1" 314 | babel-traverse "^6.24.1" 315 | babel-types "^6.24.1" 316 | 317 | babel-plugin-transform-es2015-computed-properties@^6.22.0: 318 | version "6.24.1" 319 | resolved "http://registry.npm.taobao.org/babel-plugin-transform-es2015-computed-properties/download/babel-plugin-transform-es2015-computed-properties-6.24.1.tgz#6fe2a8d16895d5634f4cd999b6d3480a308159b3" 320 | dependencies: 321 | babel-runtime "^6.22.0" 322 | babel-template "^6.24.1" 323 | 324 | babel-plugin-transform-es2015-destructuring@^6.23.0: 325 | version "6.23.0" 326 | resolved "http://registry.npm.taobao.org/babel-plugin-transform-es2015-destructuring/download/babel-plugin-transform-es2015-destructuring-6.23.0.tgz#997bb1f1ab967f682d2b0876fe358d60e765c56d" 327 | dependencies: 328 | babel-runtime "^6.22.0" 329 | 330 | babel-plugin-transform-es2015-duplicate-keys@^6.22.0: 331 | version "6.24.1" 332 | resolved "http://registry.npm.taobao.org/babel-plugin-transform-es2015-duplicate-keys/download/babel-plugin-transform-es2015-duplicate-keys-6.24.1.tgz#73eb3d310ca969e3ef9ec91c53741a6f1576423e" 333 | dependencies: 334 | babel-runtime "^6.22.0" 335 | babel-types "^6.24.1" 336 | 337 | babel-plugin-transform-es2015-for-of@^6.23.0: 338 | version "6.23.0" 339 | resolved "http://registry.npm.taobao.org/babel-plugin-transform-es2015-for-of/download/babel-plugin-transform-es2015-for-of-6.23.0.tgz#f47c95b2b613df1d3ecc2fdb7573623c75248691" 340 | dependencies: 341 | babel-runtime "^6.22.0" 342 | 343 | babel-plugin-transform-es2015-function-name@^6.22.0: 344 | version "6.24.1" 345 | resolved "http://registry.npm.taobao.org/babel-plugin-transform-es2015-function-name/download/babel-plugin-transform-es2015-function-name-6.24.1.tgz#834c89853bc36b1af0f3a4c5dbaa94fd8eacaa8b" 346 | dependencies: 347 | babel-helper-function-name "^6.24.1" 348 | babel-runtime "^6.22.0" 349 | babel-types "^6.24.1" 350 | 351 | babel-plugin-transform-es2015-literals@^6.22.0: 352 | version "6.22.0" 353 | resolved "http://registry.npm.taobao.org/babel-plugin-transform-es2015-literals/download/babel-plugin-transform-es2015-literals-6.22.0.tgz#4f54a02d6cd66cf915280019a31d31925377ca2e" 354 | dependencies: 355 | babel-runtime "^6.22.0" 356 | 357 | babel-plugin-transform-es2015-modules-amd@^6.22.0, babel-plugin-transform-es2015-modules-amd@^6.24.1: 358 | version "6.24.1" 359 | resolved "http://registry.npm.taobao.org/babel-plugin-transform-es2015-modules-amd/download/babel-plugin-transform-es2015-modules-amd-6.24.1.tgz#3b3e54017239842d6d19c3011c4bd2f00a00d154" 360 | dependencies: 361 | babel-plugin-transform-es2015-modules-commonjs "^6.24.1" 362 | babel-runtime "^6.22.0" 363 | babel-template "^6.24.1" 364 | 365 | babel-plugin-transform-es2015-modules-commonjs@^6.23.0, babel-plugin-transform-es2015-modules-commonjs@^6.24.1: 366 | version "6.26.2" 367 | resolved "http://registry.npm.taobao.org/babel-plugin-transform-es2015-modules-commonjs/download/babel-plugin-transform-es2015-modules-commonjs-6.26.2.tgz#58a793863a9e7ca870bdc5a881117ffac27db6f3" 368 | dependencies: 369 | babel-plugin-transform-strict-mode "^6.24.1" 370 | babel-runtime "^6.26.0" 371 | babel-template "^6.26.0" 372 | babel-types "^6.26.0" 373 | 374 | babel-plugin-transform-es2015-modules-systemjs@^6.23.0: 375 | version "6.24.1" 376 | resolved "http://registry.npm.taobao.org/babel-plugin-transform-es2015-modules-systemjs/download/babel-plugin-transform-es2015-modules-systemjs-6.24.1.tgz#ff89a142b9119a906195f5f106ecf305d9407d23" 377 | dependencies: 378 | babel-helper-hoist-variables "^6.24.1" 379 | babel-runtime "^6.22.0" 380 | babel-template "^6.24.1" 381 | 382 | babel-plugin-transform-es2015-modules-umd@^6.23.0: 383 | version "6.24.1" 384 | resolved "http://registry.npm.taobao.org/babel-plugin-transform-es2015-modules-umd/download/babel-plugin-transform-es2015-modules-umd-6.24.1.tgz#ac997e6285cd18ed6176adb607d602344ad38468" 385 | dependencies: 386 | babel-plugin-transform-es2015-modules-amd "^6.24.1" 387 | babel-runtime "^6.22.0" 388 | babel-template "^6.24.1" 389 | 390 | babel-plugin-transform-es2015-object-super@^6.22.0: 391 | version "6.24.1" 392 | resolved "http://registry.npm.taobao.org/babel-plugin-transform-es2015-object-super/download/babel-plugin-transform-es2015-object-super-6.24.1.tgz#24cef69ae21cb83a7f8603dad021f572eb278f8d" 393 | dependencies: 394 | babel-helper-replace-supers "^6.24.1" 395 | babel-runtime "^6.22.0" 396 | 397 | babel-plugin-transform-es2015-parameters@^6.23.0: 398 | version "6.24.1" 399 | resolved "http://registry.npm.taobao.org/babel-plugin-transform-es2015-parameters/download/babel-plugin-transform-es2015-parameters-6.24.1.tgz#57ac351ab49caf14a97cd13b09f66fdf0a625f2b" 400 | dependencies: 401 | babel-helper-call-delegate "^6.24.1" 402 | babel-helper-get-function-arity "^6.24.1" 403 | babel-runtime "^6.22.0" 404 | babel-template "^6.24.1" 405 | babel-traverse "^6.24.1" 406 | babel-types "^6.24.1" 407 | 408 | babel-plugin-transform-es2015-shorthand-properties@^6.22.0: 409 | version "6.24.1" 410 | resolved "http://registry.npm.taobao.org/babel-plugin-transform-es2015-shorthand-properties/download/babel-plugin-transform-es2015-shorthand-properties-6.24.1.tgz#24f875d6721c87661bbd99a4622e51f14de38aa0" 411 | dependencies: 412 | babel-runtime "^6.22.0" 413 | babel-types "^6.24.1" 414 | 415 | babel-plugin-transform-es2015-spread@^6.22.0: 416 | version "6.22.0" 417 | resolved "http://registry.npm.taobao.org/babel-plugin-transform-es2015-spread/download/babel-plugin-transform-es2015-spread-6.22.0.tgz#d6d68a99f89aedc4536c81a542e8dd9f1746f8d1" 418 | dependencies: 419 | babel-runtime "^6.22.0" 420 | 421 | babel-plugin-transform-es2015-sticky-regex@^6.22.0: 422 | version "6.24.1" 423 | resolved "http://registry.npm.taobao.org/babel-plugin-transform-es2015-sticky-regex/download/babel-plugin-transform-es2015-sticky-regex-6.24.1.tgz#00c1cdb1aca71112cdf0cf6126c2ed6b457ccdbc" 424 | dependencies: 425 | babel-helper-regex "^6.24.1" 426 | babel-runtime "^6.22.0" 427 | babel-types "^6.24.1" 428 | 429 | babel-plugin-transform-es2015-template-literals@^6.22.0: 430 | version "6.22.0" 431 | resolved "http://registry.npm.taobao.org/babel-plugin-transform-es2015-template-literals/download/babel-plugin-transform-es2015-template-literals-6.22.0.tgz#a84b3450f7e9f8f1f6839d6d687da84bb1236d8d" 432 | dependencies: 433 | babel-runtime "^6.22.0" 434 | 435 | babel-plugin-transform-es2015-typeof-symbol@^6.23.0: 436 | version "6.23.0" 437 | resolved "http://registry.npm.taobao.org/babel-plugin-transform-es2015-typeof-symbol/download/babel-plugin-transform-es2015-typeof-symbol-6.23.0.tgz#dec09f1cddff94b52ac73d505c84df59dcceb372" 438 | dependencies: 439 | babel-runtime "^6.22.0" 440 | 441 | babel-plugin-transform-es2015-unicode-regex@^6.22.0: 442 | version "6.24.1" 443 | resolved "http://registry.npm.taobao.org/babel-plugin-transform-es2015-unicode-regex/download/babel-plugin-transform-es2015-unicode-regex-6.24.1.tgz#d38b12f42ea7323f729387f18a7c5ae1faeb35e9" 444 | dependencies: 445 | babel-helper-regex "^6.24.1" 446 | babel-runtime "^6.22.0" 447 | regexpu-core "^2.0.0" 448 | 449 | babel-plugin-transform-exponentiation-operator@^6.22.0: 450 | version "6.24.1" 451 | resolved "http://registry.npm.taobao.org/babel-plugin-transform-exponentiation-operator/download/babel-plugin-transform-exponentiation-operator-6.24.1.tgz#2ab0c9c7f3098fa48907772bb813fe41e8de3a0e" 452 | dependencies: 453 | babel-helper-builder-binary-assignment-operator-visitor "^6.24.1" 454 | babel-plugin-syntax-exponentiation-operator "^6.8.0" 455 | babel-runtime "^6.22.0" 456 | 457 | babel-plugin-transform-object-rest-spread@^6.23.0: 458 | version "6.26.0" 459 | resolved "http://registry.npm.taobao.org/babel-plugin-transform-object-rest-spread/download/babel-plugin-transform-object-rest-spread-6.26.0.tgz#0f36692d50fef6b7e2d4b3ac1478137a963b7b06" 460 | dependencies: 461 | babel-plugin-syntax-object-rest-spread "^6.8.0" 462 | babel-runtime "^6.26.0" 463 | 464 | babel-plugin-transform-regenerator@^6.22.0: 465 | version "6.26.0" 466 | resolved "http://registry.npm.taobao.org/babel-plugin-transform-regenerator/download/babel-plugin-transform-regenerator-6.26.0.tgz#e0703696fbde27f0a3efcacf8b4dca2f7b3a8f2f" 467 | dependencies: 468 | regenerator-transform "^0.10.0" 469 | 470 | babel-plugin-transform-strict-mode@^6.24.1: 471 | version "6.24.1" 472 | resolved "http://registry.npm.taobao.org/babel-plugin-transform-strict-mode/download/babel-plugin-transform-strict-mode-6.24.1.tgz#d5faf7aa578a65bbe591cf5edae04a0c67020758" 473 | dependencies: 474 | babel-runtime "^6.22.0" 475 | babel-types "^6.24.1" 476 | 477 | babel-polyfill@^6.26.0: 478 | version "6.26.0" 479 | resolved "http://registry.npm.taobao.org/babel-polyfill/download/babel-polyfill-6.26.0.tgz#379937abc67d7895970adc621f284cd966cf2153" 480 | dependencies: 481 | babel-runtime "^6.26.0" 482 | core-js "^2.5.0" 483 | regenerator-runtime "^0.10.5" 484 | 485 | babel-preset-env@^1.5.2: 486 | version "1.7.0" 487 | resolved "http://registry.npm.taobao.org/babel-preset-env/download/babel-preset-env-1.7.0.tgz#dea79fa4ebeb883cd35dab07e260c1c9c04df77a" 488 | dependencies: 489 | babel-plugin-check-es2015-constants "^6.22.0" 490 | babel-plugin-syntax-trailing-function-commas "^6.22.0" 491 | babel-plugin-transform-async-to-generator "^6.22.0" 492 | babel-plugin-transform-es2015-arrow-functions "^6.22.0" 493 | babel-plugin-transform-es2015-block-scoped-functions "^6.22.0" 494 | babel-plugin-transform-es2015-block-scoping "^6.23.0" 495 | babel-plugin-transform-es2015-classes "^6.23.0" 496 | babel-plugin-transform-es2015-computed-properties "^6.22.0" 497 | babel-plugin-transform-es2015-destructuring "^6.23.0" 498 | babel-plugin-transform-es2015-duplicate-keys "^6.22.0" 499 | babel-plugin-transform-es2015-for-of "^6.23.0" 500 | babel-plugin-transform-es2015-function-name "^6.22.0" 501 | babel-plugin-transform-es2015-literals "^6.22.0" 502 | babel-plugin-transform-es2015-modules-amd "^6.22.0" 503 | babel-plugin-transform-es2015-modules-commonjs "^6.23.0" 504 | babel-plugin-transform-es2015-modules-systemjs "^6.23.0" 505 | babel-plugin-transform-es2015-modules-umd "^6.23.0" 506 | babel-plugin-transform-es2015-object-super "^6.22.0" 507 | babel-plugin-transform-es2015-parameters "^6.23.0" 508 | babel-plugin-transform-es2015-shorthand-properties "^6.22.0" 509 | babel-plugin-transform-es2015-spread "^6.22.0" 510 | babel-plugin-transform-es2015-sticky-regex "^6.22.0" 511 | babel-plugin-transform-es2015-template-literals "^6.22.0" 512 | babel-plugin-transform-es2015-typeof-symbol "^6.23.0" 513 | babel-plugin-transform-es2015-unicode-regex "^6.22.0" 514 | babel-plugin-transform-exponentiation-operator "^6.22.0" 515 | babel-plugin-transform-regenerator "^6.22.0" 516 | browserslist "^3.2.6" 517 | invariant "^2.2.2" 518 | semver "^5.3.0" 519 | 520 | babel-register@^6.26.0: 521 | version "6.26.0" 522 | resolved "http://registry.npm.taobao.org/babel-register/download/babel-register-6.26.0.tgz#6ed021173e2fcb486d7acb45c6009a856f647071" 523 | dependencies: 524 | babel-core "^6.26.0" 525 | babel-runtime "^6.26.0" 526 | core-js "^2.5.0" 527 | home-or-tmp "^2.0.0" 528 | lodash "^4.17.4" 529 | mkdirp "^0.5.1" 530 | source-map-support "^0.4.15" 531 | 532 | babel-runtime@^6.18.0, babel-runtime@^6.2.0, babel-runtime@^6.22.0, babel-runtime@^6.26.0: 533 | version "6.26.0" 534 | resolved "http://registry.npm.taobao.org/babel-runtime/download/babel-runtime-6.26.0.tgz#965c7058668e82b55d7bfe04ff2337bc8b5647fe" 535 | dependencies: 536 | core-js "^2.4.0" 537 | regenerator-runtime "^0.11.0" 538 | 539 | babel-template@^6.24.1, babel-template@^6.26.0, babel-template@^6.3.0: 540 | version "6.26.0" 541 | resolved "http://registry.npm.taobao.org/babel-template/download/babel-template-6.26.0.tgz#de03e2d16396b069f46dd9fff8521fb1a0e35e02" 542 | dependencies: 543 | babel-runtime "^6.26.0" 544 | babel-traverse "^6.26.0" 545 | babel-types "^6.26.0" 546 | babylon "^6.18.0" 547 | lodash "^4.17.4" 548 | 549 | babel-traverse@^6.24.1, babel-traverse@^6.26.0: 550 | version "6.26.0" 551 | resolved "http://registry.npm.taobao.org/babel-traverse/download/babel-traverse-6.26.0.tgz#46a9cbd7edcc62c8e5c064e2d2d8d0f4035766ee" 552 | dependencies: 553 | babel-code-frame "^6.26.0" 554 | babel-messages "^6.23.0" 555 | babel-runtime "^6.26.0" 556 | babel-types "^6.26.0" 557 | babylon "^6.18.0" 558 | debug "^2.6.8" 559 | globals "^9.18.0" 560 | invariant "^2.2.2" 561 | lodash "^4.17.4" 562 | 563 | babel-types@^6.19.0, babel-types@^6.24.1, babel-types@^6.26.0: 564 | version "6.26.0" 565 | resolved "http://registry.npm.taobao.org/babel-types/download/babel-types-6.26.0.tgz#a3b073f94ab49eb6fa55cd65227a334380632497" 566 | dependencies: 567 | babel-runtime "^6.26.0" 568 | esutils "^2.0.2" 569 | lodash "^4.17.4" 570 | to-fast-properties "^1.0.3" 571 | 572 | babel@^6.23.0: 573 | version "6.23.0" 574 | resolved "http://registry.npm.taobao.org/babel/download/babel-6.23.0.tgz#d0d1e7d803e974765beea3232d4e153c0efb90f4" 575 | 576 | babylon@^6.18.0: 577 | version "6.18.0" 578 | resolved "http://registry.npm.taobao.org/babylon/download/babylon-6.18.0.tgz#af2f3b88fa6f5c1e4c634d1a0f8eac4f55b395e3" 579 | 580 | balanced-match@^1.0.0: 581 | version "1.0.0" 582 | resolved "http://registry.npm.taobao.org/balanced-match/download/balanced-match-1.0.0.tgz#89b4d199ab2bee49de164ea02b89ce462d71b767" 583 | 584 | binary-extensions@^1.0.0: 585 | version "1.11.0" 586 | resolved "http://registry.npm.taobao.org/binary-extensions/download/binary-extensions-1.11.0.tgz#46aa1751fb6a2f93ee5e689bb1087d4b14c6c205" 587 | 588 | brace-expansion@^1.1.7: 589 | version "1.1.11" 590 | resolved "http://registry.npm.taobao.org/brace-expansion/download/brace-expansion-1.1.11.tgz#3c7fcbf529d87226f3d2f52b966ff5271eb441dd" 591 | dependencies: 592 | balanced-match "^1.0.0" 593 | concat-map "0.0.1" 594 | 595 | braces@^1.8.2: 596 | version "1.8.5" 597 | resolved "http://registry.npm.taobao.org/braces/download/braces-1.8.5.tgz#ba77962e12dff969d6b76711e914b737857bf6a7" 598 | dependencies: 599 | expand-range "^1.8.1" 600 | preserve "^0.2.0" 601 | repeat-element "^1.1.2" 602 | 603 | browserslist@^3.2.6: 604 | version "3.2.8" 605 | resolved "http://registry.npm.taobao.org/browserslist/download/browserslist-3.2.8.tgz#b0005361d6471f0f5952797a76fc985f1f978fc6" 606 | dependencies: 607 | caniuse-lite "^1.0.30000844" 608 | electron-to-chromium "^1.3.47" 609 | 610 | caniuse-lite@^1.0.30000844: 611 | version "1.0.30000844" 612 | resolved "http://registry.npm.taobao.org/caniuse-lite/download/caniuse-lite-1.0.30000844.tgz#de7c84cde0582143cf4f5abdf1b98e5a0539ad4a" 613 | 614 | chalk@^1.1.3: 615 | version "1.1.3" 616 | resolved "http://registry.npm.taobao.org/chalk/download/chalk-1.1.3.tgz#a8115c55e4a702fe4d150abd3872822a7e09fc98" 617 | dependencies: 618 | ansi-styles "^2.2.1" 619 | escape-string-regexp "^1.0.2" 620 | has-ansi "^2.0.0" 621 | strip-ansi "^3.0.0" 622 | supports-color "^2.0.0" 623 | 624 | chokidar@^1.6.1: 625 | version "1.7.0" 626 | resolved "http://registry.npm.taobao.org/chokidar/download/chokidar-1.7.0.tgz#798e689778151c8076b4b360e5edd28cda2bb468" 627 | dependencies: 628 | anymatch "^1.3.0" 629 | async-each "^1.0.0" 630 | glob-parent "^2.0.0" 631 | inherits "^2.0.1" 632 | is-binary-path "^1.0.0" 633 | is-glob "^2.0.0" 634 | path-is-absolute "^1.0.0" 635 | readdirp "^2.0.0" 636 | optionalDependencies: 637 | fsevents "^1.0.0" 638 | 639 | chownr@^1.0.1: 640 | version "1.0.1" 641 | resolved "http://registry.npm.taobao.org/chownr/download/chownr-1.0.1.tgz#e2a75042a9551908bebd25b8523d5f9769d79181" 642 | 643 | code-point-at@^1.0.0: 644 | version "1.1.0" 645 | resolved "http://registry.npm.taobao.org/code-point-at/download/code-point-at-1.1.0.tgz#0d070b4d043a5bea33a2f1a40e2edb3d9a4ccf77" 646 | 647 | commander@^2.11.0: 648 | version "2.15.1" 649 | resolved "http://registry.npm.taobao.org/commander/download/commander-2.15.1.tgz#df46e867d0fc2aec66a34662b406a9ccafff5b0f" 650 | 651 | concat-map@0.0.1: 652 | version "0.0.1" 653 | resolved "http://registry.npm.taobao.org/concat-map/download/concat-map-0.0.1.tgz#d8a96bd77fd68df7793a73036a3ba0d5405d477b" 654 | 655 | console-control-strings@^1.0.0, console-control-strings@~1.1.0: 656 | version "1.1.0" 657 | resolved "http://registry.npm.taobao.org/console-control-strings/download/console-control-strings-1.1.0.tgz#3d7cf4464db6446ea644bf4b39507f9851008e8e" 658 | 659 | convert-source-map@^1.5.0, convert-source-map@^1.5.1: 660 | version "1.5.1" 661 | resolved "http://registry.npm.taobao.org/convert-source-map/download/convert-source-map-1.5.1.tgz#b8278097b9bc229365de5c62cf5fcaed8b5599e5" 662 | 663 | core-js@^2.4.0, core-js@^2.5.0: 664 | version "2.5.6" 665 | resolved "http://registry.npm.taobao.org/core-js/download/core-js-2.5.6.tgz#0fe6d45bf3cac3ac364a9d72de7576f4eb221b9d" 666 | 667 | core-util-is@~1.0.0: 668 | version "1.0.2" 669 | resolved "http://registry.npm.taobao.org/core-util-is/download/core-util-is-1.0.2.tgz#b5fd54220aa2bc5ab57aab7140c940754503c1a7" 670 | 671 | cross-env@^5.0.1: 672 | version "5.1.6" 673 | resolved "http://registry.npm.taobao.org/cross-env/download/cross-env-5.1.6.tgz#0dc05caf945b24e4b9e3b12871fe0e858d08b38d" 674 | dependencies: 675 | cross-spawn "^5.1.0" 676 | is-windows "^1.0.0" 677 | 678 | cross-spawn@^5.1.0: 679 | version "5.1.0" 680 | resolved "http://registry.npm.taobao.org/cross-spawn/download/cross-spawn-5.1.0.tgz#e8bd0efee58fcff6f8f94510a0a554bbfa235449" 681 | dependencies: 682 | lru-cache "^4.0.1" 683 | shebang-command "^1.2.0" 684 | which "^1.2.9" 685 | 686 | debug@^2.1.2, debug@^2.6.8, debug@^2.6.9: 687 | version "2.6.9" 688 | resolved "http://registry.npm.taobao.org/debug/download/debug-2.6.9.tgz#5d128515df134ff327e90a4c93f4e077a536341f" 689 | dependencies: 690 | ms "2.0.0" 691 | 692 | deep-extend@^0.5.1: 693 | version "0.5.1" 694 | resolved "http://registry.npm.taobao.org/deep-extend/download/deep-extend-0.5.1.tgz#b894a9dd90d3023fbf1c55a394fb858eb2066f1f" 695 | 696 | delegates@^1.0.0: 697 | version "1.0.0" 698 | resolved "http://registry.npm.taobao.org/delegates/download/delegates-1.0.0.tgz#84c6e159b81904fdca59a0ef44cd870d31250f9a" 699 | 700 | detect-indent@^4.0.0: 701 | version "4.0.0" 702 | resolved "http://registry.npm.taobao.org/detect-indent/download/detect-indent-4.0.0.tgz#f76d064352cdf43a1cb6ce619c4ee3a9475de208" 703 | dependencies: 704 | repeating "^2.0.0" 705 | 706 | detect-libc@^1.0.2: 707 | version "1.0.3" 708 | resolved "http://registry.npm.taobao.org/detect-libc/download/detect-libc-1.0.3.tgz#fa137c4bd698edf55cd5cd02ac559f91a4c4ba9b" 709 | 710 | electron-to-chromium@^1.3.47: 711 | version "1.3.48" 712 | resolved "http://registry.npm.taobao.org/electron-to-chromium/download/electron-to-chromium-1.3.48.tgz#d3b0d8593814044e092ece2108fc3ac9aea4b900" 713 | 714 | escape-string-regexp@^1.0.2: 715 | version "1.0.5" 716 | resolved "http://registry.npm.taobao.org/escape-string-regexp/download/escape-string-regexp-1.0.5.tgz#1b61c0562190a8dff6ae3bb2cf0200ca130b86d4" 717 | 718 | esutils@^2.0.2: 719 | version "2.0.2" 720 | resolved "http://registry.npm.taobao.org/esutils/download/esutils-2.0.2.tgz#0abf4f1caa5bcb1f7a9d8acc6dea4faaa04bac9b" 721 | 722 | expand-brackets@^0.1.4: 723 | version "0.1.5" 724 | resolved "http://registry.npm.taobao.org/expand-brackets/download/expand-brackets-0.1.5.tgz#df07284e342a807cd733ac5af72411e581d1177b" 725 | dependencies: 726 | is-posix-bracket "^0.1.0" 727 | 728 | expand-range@^1.8.1: 729 | version "1.8.2" 730 | resolved "http://registry.npm.taobao.org/expand-range/download/expand-range-1.8.2.tgz#a299effd335fe2721ebae8e257ec79644fc85337" 731 | dependencies: 732 | fill-range "^2.1.0" 733 | 734 | extglob@^0.3.1: 735 | version "0.3.2" 736 | resolved "http://registry.npm.taobao.org/extglob/download/extglob-0.3.2.tgz#2e18ff3d2f49ab2765cec9023f011daa8d8349a1" 737 | dependencies: 738 | is-extglob "^1.0.0" 739 | 740 | filename-regex@^2.0.0: 741 | version "2.0.1" 742 | resolved "http://registry.npm.taobao.org/filename-regex/download/filename-regex-2.0.1.tgz#c1c4b9bee3e09725ddb106b75c1e301fe2f18b26" 743 | 744 | fill-range@^2.1.0: 745 | version "2.2.4" 746 | resolved "http://registry.npm.taobao.org/fill-range/download/fill-range-2.2.4.tgz#eb1e773abb056dcd8df2bfdf6af59b8b3a936565" 747 | dependencies: 748 | is-number "^2.1.0" 749 | isobject "^2.0.0" 750 | randomatic "^3.0.0" 751 | repeat-element "^1.1.2" 752 | repeat-string "^1.5.2" 753 | 754 | for-in@^1.0.1: 755 | version "1.0.2" 756 | resolved "http://registry.npm.taobao.org/for-in/download/for-in-1.0.2.tgz#81068d295a8142ec0ac726c6e2200c30fb6d5e80" 757 | 758 | for-own@^0.1.4: 759 | version "0.1.5" 760 | resolved "http://registry.npm.taobao.org/for-own/download/for-own-0.1.5.tgz#5265c681a4f294dabbf17c9509b6763aa84510ce" 761 | dependencies: 762 | for-in "^1.0.1" 763 | 764 | fs-minipass@^1.2.5: 765 | version "1.2.5" 766 | resolved "http://registry.npm.taobao.org/fs-minipass/download/fs-minipass-1.2.5.tgz#06c277218454ec288df77ada54a03b8702aacb9d" 767 | dependencies: 768 | minipass "^2.2.1" 769 | 770 | fs-readdir-recursive@^1.0.0: 771 | version "1.1.0" 772 | resolved "http://registry.npm.taobao.org/fs-readdir-recursive/download/fs-readdir-recursive-1.1.0.tgz#e32fc030a2ccee44a6b5371308da54be0b397d27" 773 | 774 | fs.realpath@^1.0.0: 775 | version "1.0.0" 776 | resolved "http://registry.npm.taobao.org/fs.realpath/download/fs.realpath-1.0.0.tgz#1504ad2523158caa40db4a2787cb01411994ea4f" 777 | 778 | fsevents@^1.0.0: 779 | version "1.2.4" 780 | resolved "http://registry.npm.taobao.org/fsevents/download/fsevents-1.2.4.tgz#f41dcb1af2582af3692da36fc55cbd8e1041c426" 781 | dependencies: 782 | nan "^2.9.2" 783 | node-pre-gyp "^0.10.0" 784 | 785 | gauge@~2.7.3: 786 | version "2.7.4" 787 | resolved "http://registry.npm.taobao.org/gauge/download/gauge-2.7.4.tgz#2c03405c7538c39d7eb37b317022e325fb018bf7" 788 | dependencies: 789 | aproba "^1.0.3" 790 | console-control-strings "^1.0.0" 791 | has-unicode "^2.0.0" 792 | object-assign "^4.1.0" 793 | signal-exit "^3.0.0" 794 | string-width "^1.0.1" 795 | strip-ansi "^3.0.1" 796 | wide-align "^1.1.0" 797 | 798 | glob-base@^0.3.0: 799 | version "0.3.0" 800 | resolved "http://registry.npm.taobao.org/glob-base/download/glob-base-0.3.0.tgz#dbb164f6221b1c0b1ccf82aea328b497df0ea3c4" 801 | dependencies: 802 | glob-parent "^2.0.0" 803 | is-glob "^2.0.0" 804 | 805 | glob-parent@^2.0.0: 806 | version "2.0.0" 807 | resolved "http://registry.npm.taobao.org/glob-parent/download/glob-parent-2.0.0.tgz#81383d72db054fcccf5336daa902f182f6edbb28" 808 | dependencies: 809 | is-glob "^2.0.0" 810 | 811 | glob@^7.0.5, glob@^7.1.2: 812 | version "7.1.2" 813 | resolved "http://registry.npm.taobao.org/glob/download/glob-7.1.2.tgz#c19c9df9a028702d678612384a6552404c636d15" 814 | dependencies: 815 | fs.realpath "^1.0.0" 816 | inflight "^1.0.4" 817 | inherits "2" 818 | minimatch "^3.0.4" 819 | once "^1.3.0" 820 | path-is-absolute "^1.0.0" 821 | 822 | globals@^9.18.0: 823 | version "9.18.0" 824 | resolved "http://registry.npm.taobao.org/globals/download/globals-9.18.0.tgz#aa3896b3e69b487f17e31ed2143d69a8e30c2d8a" 825 | 826 | graceful-fs@^4.1.2, graceful-fs@^4.1.4: 827 | version "4.1.11" 828 | resolved "http://registry.npm.taobao.org/graceful-fs/download/graceful-fs-4.1.11.tgz#0e8bdfe4d1ddb8854d64e04ea7c00e2a026e5658" 829 | 830 | has-ansi@^2.0.0: 831 | version "2.0.0" 832 | resolved "http://registry.npm.taobao.org/has-ansi/download/has-ansi-2.0.0.tgz#34f5049ce1ecdf2b0649af3ef24e45ed35416d91" 833 | dependencies: 834 | ansi-regex "^2.0.0" 835 | 836 | has-unicode@^2.0.0: 837 | version "2.0.1" 838 | resolved "http://registry.npm.taobao.org/has-unicode/download/has-unicode-2.0.1.tgz#e0e6fe6a28cf51138855e086d1691e771de2a8b9" 839 | 840 | home-or-tmp@^2.0.0: 841 | version "2.0.0" 842 | resolved "http://registry.npm.taobao.org/home-or-tmp/download/home-or-tmp-2.0.0.tgz#e36c3f2d2cae7d746a857e38d18d5f32a7882db8" 843 | dependencies: 844 | os-homedir "^1.0.0" 845 | os-tmpdir "^1.0.1" 846 | 847 | iconv-lite@^0.4.4: 848 | version "0.4.23" 849 | resolved "http://registry.npm.taobao.org/iconv-lite/download/iconv-lite-0.4.23.tgz#297871f63be507adcfbfca715d0cd0eed84e9a63" 850 | dependencies: 851 | safer-buffer ">= 2.1.2 < 3" 852 | 853 | ignore-walk@^3.0.1: 854 | version "3.0.1" 855 | resolved "http://registry.npm.taobao.org/ignore-walk/download/ignore-walk-3.0.1.tgz#a83e62e7d272ac0e3b551aaa82831a19b69f82f8" 856 | dependencies: 857 | minimatch "^3.0.4" 858 | 859 | inflight@^1.0.4: 860 | version "1.0.6" 861 | resolved "http://registry.npm.taobao.org/inflight/download/inflight-1.0.6.tgz#49bd6331d7d02d0c09bc910a1075ba8165b56df9" 862 | dependencies: 863 | once "^1.3.0" 864 | wrappy "1" 865 | 866 | inherits@2, inherits@^2.0.1, inherits@~2.0.3: 867 | version "2.0.3" 868 | resolved "http://registry.npm.taobao.org/inherits/download/inherits-2.0.3.tgz#633c2c83e3da42a502f52466022480f4208261de" 869 | 870 | ini@~1.3.0: 871 | version "1.3.5" 872 | resolved "http://registry.npm.taobao.org/ini/download/ini-1.3.5.tgz#eee25f56db1c9ec6085e0c22778083f596abf927" 873 | 874 | invariant@^2.2.2: 875 | version "2.2.4" 876 | resolved "http://registry.npm.taobao.org/invariant/download/invariant-2.2.4.tgz#610f3c92c9359ce1db616e538008d23ff35158e6" 877 | dependencies: 878 | loose-envify "^1.0.0" 879 | 880 | is-binary-path@^1.0.0: 881 | version "1.0.1" 882 | resolved "http://registry.npm.taobao.org/is-binary-path/download/is-binary-path-1.0.1.tgz#75f16642b480f187a711c814161fd3a4a7655898" 883 | dependencies: 884 | binary-extensions "^1.0.0" 885 | 886 | is-buffer@^1.1.5: 887 | version "1.1.6" 888 | resolved "http://registry.npm.taobao.org/is-buffer/download/is-buffer-1.1.6.tgz#efaa2ea9daa0d7ab2ea13a97b2b8ad51fefbe8be" 889 | 890 | is-dotfile@^1.0.0: 891 | version "1.0.3" 892 | resolved "http://registry.npm.taobao.org/is-dotfile/download/is-dotfile-1.0.3.tgz#a6a2f32ffd2dfb04f5ca25ecd0f6b83cf798a1e1" 893 | 894 | is-equal-shallow@^0.1.3: 895 | version "0.1.3" 896 | resolved "http://registry.npm.taobao.org/is-equal-shallow/download/is-equal-shallow-0.1.3.tgz#2238098fc221de0bcfa5d9eac4c45d638aa1c534" 897 | dependencies: 898 | is-primitive "^2.0.0" 899 | 900 | is-extendable@^0.1.1: 901 | version "0.1.1" 902 | resolved "http://registry.npm.taobao.org/is-extendable/download/is-extendable-0.1.1.tgz#62b110e289a471418e3ec36a617d472e301dfc89" 903 | 904 | is-extglob@^1.0.0: 905 | version "1.0.0" 906 | resolved "http://registry.npm.taobao.org/is-extglob/download/is-extglob-1.0.0.tgz#ac468177c4943405a092fc8f29760c6ffc6206c0" 907 | 908 | is-finite@^1.0.0: 909 | version "1.0.2" 910 | resolved "http://registry.npm.taobao.org/is-finite/download/is-finite-1.0.2.tgz#cc6677695602be550ef11e8b4aa6305342b6d0aa" 911 | dependencies: 912 | number-is-nan "^1.0.0" 913 | 914 | is-fullwidth-code-point@^1.0.0: 915 | version "1.0.0" 916 | resolved "http://registry.npm.taobao.org/is-fullwidth-code-point/download/is-fullwidth-code-point-1.0.0.tgz#ef9e31386f031a7f0d643af82fde50c457ef00cb" 917 | dependencies: 918 | number-is-nan "^1.0.0" 919 | 920 | is-glob@^2.0.0, is-glob@^2.0.1: 921 | version "2.0.1" 922 | resolved "http://registry.npm.taobao.org/is-glob/download/is-glob-2.0.1.tgz#d096f926a3ded5600f3fdfd91198cb0888c2d863" 923 | dependencies: 924 | is-extglob "^1.0.0" 925 | 926 | is-number@^2.1.0: 927 | version "2.1.0" 928 | resolved "http://registry.npm.taobao.org/is-number/download/is-number-2.1.0.tgz#01fcbbb393463a548f2f466cce16dece49db908f" 929 | dependencies: 930 | kind-of "^3.0.2" 931 | 932 | is-number@^4.0.0: 933 | version "4.0.0" 934 | resolved "http://registry.npm.taobao.org/is-number/download/is-number-4.0.0.tgz#0026e37f5454d73e356dfe6564699867c6a7f0ff" 935 | 936 | is-posix-bracket@^0.1.0: 937 | version "0.1.1" 938 | resolved "http://registry.npm.taobao.org/is-posix-bracket/download/is-posix-bracket-0.1.1.tgz#3334dc79774368e92f016e6fbc0a88f5cd6e6bc4" 939 | 940 | is-primitive@^2.0.0: 941 | version "2.0.0" 942 | resolved "http://registry.npm.taobao.org/is-primitive/download/is-primitive-2.0.0.tgz#207bab91638499c07b2adf240a41a87210034575" 943 | 944 | is-windows@^1.0.0: 945 | version "1.0.2" 946 | resolved "http://registry.npm.taobao.org/is-windows/download/is-windows-1.0.2.tgz#d1850eb9791ecd18e6182ce12a30f396634bb19d" 947 | 948 | isarray@1.0.0, isarray@~1.0.0: 949 | version "1.0.0" 950 | resolved "http://registry.npm.taobao.org/isarray/download/isarray-1.0.0.tgz#bb935d48582cba168c06834957a54a3e07124f11" 951 | 952 | isexe@^2.0.0: 953 | version "2.0.0" 954 | resolved "http://registry.npm.taobao.org/isexe/download/isexe-2.0.0.tgz#e8fbf374dc556ff8947a10dcb0572d633f2cfa10" 955 | 956 | isobject@^2.0.0: 957 | version "2.1.0" 958 | resolved "http://registry.npm.taobao.org/isobject/download/isobject-2.1.0.tgz#f065561096a3f1da2ef46272f815c840d87e0c89" 959 | dependencies: 960 | isarray "1.0.0" 961 | 962 | js-tokens@^3.0.0, js-tokens@^3.0.2: 963 | version "3.0.2" 964 | resolved "http://registry.npm.taobao.org/js-tokens/download/js-tokens-3.0.2.tgz#9866df395102130e38f7f996bceb65443209c25b" 965 | 966 | jsesc@^1.3.0: 967 | version "1.3.0" 968 | resolved "http://registry.npm.taobao.org/jsesc/download/jsesc-1.3.0.tgz#46c3fec8c1892b12b0833db9bc7622176dbab34b" 969 | 970 | jsesc@~0.5.0: 971 | version "0.5.0" 972 | resolved "http://registry.npm.taobao.org/jsesc/download/jsesc-0.5.0.tgz#e7dee66e35d6fc16f710fe91d5cf69f70f08911d" 973 | 974 | json5@^0.5.1: 975 | version "0.5.1" 976 | resolved "http://registry.npm.taobao.org/json5/download/json5-0.5.1.tgz#1eade7acc012034ad84e2396767ead9fa5495821" 977 | 978 | kind-of@^3.0.2: 979 | version "3.2.2" 980 | resolved "http://registry.npm.taobao.org/kind-of/download/kind-of-3.2.2.tgz#31ea21a734bab9bbb0f32466d893aea51e4a3c64" 981 | dependencies: 982 | is-buffer "^1.1.5" 983 | 984 | kind-of@^6.0.0: 985 | version "6.0.2" 986 | resolved "http://registry.npm.taobao.org/kind-of/download/kind-of-6.0.2.tgz#01146b36a6218e64e58f3a8d66de5d7fc6f6d051" 987 | 988 | lodash@^4.17.4: 989 | version "4.17.10" 990 | resolved "http://registry.npm.taobao.org/lodash/download/lodash-4.17.10.tgz#1b7793cf7259ea38fb3661d4d38b3260af8ae4e7" 991 | 992 | loose-envify@^1.0.0: 993 | version "1.3.1" 994 | resolved "http://registry.npm.taobao.org/loose-envify/download/loose-envify-1.3.1.tgz#d1a8ad33fa9ce0e713d65fdd0ac8b748d478c848" 995 | dependencies: 996 | js-tokens "^3.0.0" 997 | 998 | lru-cache@^4.0.1: 999 | version "4.1.3" 1000 | resolved "http://registry.npm.taobao.org/lru-cache/download/lru-cache-4.1.3.tgz#a1175cf3496dfc8436c156c334b4955992bce69c" 1001 | dependencies: 1002 | pseudomap "^1.0.2" 1003 | yallist "^2.1.2" 1004 | 1005 | math-random@^1.0.1: 1006 | version "1.0.1" 1007 | resolved "http://registry.npm.taobao.org/math-random/download/math-random-1.0.1.tgz#8b3aac588b8a66e4975e3cdea67f7bb329601fac" 1008 | 1009 | micromatch@^2.1.5: 1010 | version "2.3.11" 1011 | resolved "http://registry.npm.taobao.org/micromatch/download/micromatch-2.3.11.tgz#86677c97d1720b363431d04d0d15293bd38c1565" 1012 | dependencies: 1013 | arr-diff "^2.0.0" 1014 | array-unique "^0.2.1" 1015 | braces "^1.8.2" 1016 | expand-brackets "^0.1.4" 1017 | extglob "^0.3.1" 1018 | filename-regex "^2.0.0" 1019 | is-extglob "^1.0.0" 1020 | is-glob "^2.0.1" 1021 | kind-of "^3.0.2" 1022 | normalize-path "^2.0.1" 1023 | object.omit "^2.0.0" 1024 | parse-glob "^3.0.4" 1025 | regex-cache "^0.4.2" 1026 | 1027 | minimatch@^3.0.2, minimatch@^3.0.4: 1028 | version "3.0.4" 1029 | resolved "http://registry.npm.taobao.org/minimatch/download/minimatch-3.0.4.tgz#5166e286457f03306064be5497e8dbb0c3d32083" 1030 | dependencies: 1031 | brace-expansion "^1.1.7" 1032 | 1033 | minimist@0.0.8: 1034 | version "0.0.8" 1035 | resolved "http://registry.npm.taobao.org/minimist/download/minimist-0.0.8.tgz#857fcabfc3397d2625b8228262e86aa7a011b05d" 1036 | 1037 | minimist@^1.2.0: 1038 | version "1.2.0" 1039 | resolved "http://registry.npm.taobao.org/minimist/download/minimist-1.2.0.tgz#a35008b20f41383eec1fb914f4cd5df79a264284" 1040 | 1041 | minipass@^2.2.1, minipass@^2.2.4: 1042 | version "2.3.3" 1043 | resolved "http://registry.npm.taobao.org/minipass/download/minipass-2.3.3.tgz#a7dcc8b7b833f5d368759cce544dccb55f50f233" 1044 | dependencies: 1045 | safe-buffer "^5.1.2" 1046 | yallist "^3.0.0" 1047 | 1048 | minizlib@^1.1.0: 1049 | version "1.1.0" 1050 | resolved "http://registry.npm.taobao.org/minizlib/download/minizlib-1.1.0.tgz#11e13658ce46bc3a70a267aac58359d1e0c29ceb" 1051 | dependencies: 1052 | minipass "^2.2.1" 1053 | 1054 | mkdirp@^0.5.0, mkdirp@^0.5.1: 1055 | version "0.5.1" 1056 | resolved "http://registry.npm.taobao.org/mkdirp/download/mkdirp-0.5.1.tgz#30057438eac6cf7f8c4767f38648d6697d75c903" 1057 | dependencies: 1058 | minimist "0.0.8" 1059 | 1060 | ms@2.0.0: 1061 | version "2.0.0" 1062 | resolved "http://registry.npm.taobao.org/ms/download/ms-2.0.0.tgz#5608aeadfc00be6c2901df5f9861788de0d597c8" 1063 | 1064 | nan@^2.9.2: 1065 | version "2.10.0" 1066 | resolved "http://registry.npm.taobao.org/nan/download/nan-2.10.0.tgz#96d0cd610ebd58d4b4de9cc0c6828cda99c7548f" 1067 | 1068 | needle@^2.2.0: 1069 | version "2.2.1" 1070 | resolved "http://registry.npm.taobao.org/needle/download/needle-2.2.1.tgz#b5e325bd3aae8c2678902fa296f729455d1d3a7d" 1071 | dependencies: 1072 | debug "^2.1.2" 1073 | iconv-lite "^0.4.4" 1074 | sax "^1.2.4" 1075 | 1076 | node-pre-gyp@^0.10.0: 1077 | version "0.10.0" 1078 | resolved "http://registry.npm.taobao.org/node-pre-gyp/download/node-pre-gyp-0.10.0.tgz#6e4ef5bb5c5203c6552448828c852c40111aac46" 1079 | dependencies: 1080 | detect-libc "^1.0.2" 1081 | mkdirp "^0.5.1" 1082 | needle "^2.2.0" 1083 | nopt "^4.0.1" 1084 | npm-packlist "^1.1.6" 1085 | npmlog "^4.0.2" 1086 | rc "^1.1.7" 1087 | rimraf "^2.6.1" 1088 | semver "^5.3.0" 1089 | tar "^4" 1090 | 1091 | nopt@^4.0.1: 1092 | version "4.0.1" 1093 | resolved "http://registry.npm.taobao.org/nopt/download/nopt-4.0.1.tgz#d0d4685afd5415193c8c7505602d0d17cd64474d" 1094 | dependencies: 1095 | abbrev "1" 1096 | osenv "^0.1.4" 1097 | 1098 | normalize-path@^2.0.0, normalize-path@^2.0.1: 1099 | version "2.1.1" 1100 | resolved "http://registry.npm.taobao.org/normalize-path/download/normalize-path-2.1.1.tgz#1ab28b556e198363a8c1a6f7e6fa20137fe6aed9" 1101 | dependencies: 1102 | remove-trailing-separator "^1.0.1" 1103 | 1104 | npm-bundled@^1.0.1: 1105 | version "1.0.3" 1106 | resolved "http://registry.npm.taobao.org/npm-bundled/download/npm-bundled-1.0.3.tgz#7e71703d973af3370a9591bafe3a63aca0be2308" 1107 | 1108 | npm-packlist@^1.1.6: 1109 | version "1.1.10" 1110 | resolved "http://registry.npm.taobao.org/npm-packlist/download/npm-packlist-1.1.10.tgz#1039db9e985727e464df066f4cf0ab6ef85c398a" 1111 | dependencies: 1112 | ignore-walk "^3.0.1" 1113 | npm-bundled "^1.0.1" 1114 | 1115 | npmlog@^4.0.2: 1116 | version "4.1.2" 1117 | resolved "http://registry.npm.taobao.org/npmlog/download/npmlog-4.1.2.tgz#08a7f2a8bf734604779a9efa4ad5cc717abb954b" 1118 | dependencies: 1119 | are-we-there-yet "~1.1.2" 1120 | console-control-strings "~1.1.0" 1121 | gauge "~2.7.3" 1122 | set-blocking "~2.0.0" 1123 | 1124 | number-is-nan@^1.0.0: 1125 | version "1.0.1" 1126 | resolved "http://registry.npm.taobao.org/number-is-nan/download/number-is-nan-1.0.1.tgz#097b602b53422a522c1afb8790318336941a011d" 1127 | 1128 | object-assign@^4.1.0: 1129 | version "4.1.1" 1130 | resolved "http://registry.npm.taobao.org/object-assign/download/object-assign-4.1.1.tgz#2109adc7965887cfc05cbbd442cac8bfbb360863" 1131 | 1132 | object.omit@^2.0.0: 1133 | version "2.0.1" 1134 | resolved "http://registry.npm.taobao.org/object.omit/download/object.omit-2.0.1.tgz#1a9c744829f39dbb858c76ca3579ae2a54ebd1fa" 1135 | dependencies: 1136 | for-own "^0.1.4" 1137 | is-extendable "^0.1.1" 1138 | 1139 | once@^1.3.0: 1140 | version "1.4.0" 1141 | resolved "http://registry.npm.taobao.org/once/download/once-1.4.0.tgz#583b1aa775961d4b113ac17d9c50baef9dd76bd1" 1142 | dependencies: 1143 | wrappy "1" 1144 | 1145 | os-homedir@^1.0.0: 1146 | version "1.0.2" 1147 | resolved "http://registry.npm.taobao.org/os-homedir/download/os-homedir-1.0.2.tgz#ffbc4988336e0e833de0c168c7ef152121aa7fb3" 1148 | 1149 | os-tmpdir@^1.0.0, os-tmpdir@^1.0.1: 1150 | version "1.0.2" 1151 | resolved "http://registry.npm.taobao.org/os-tmpdir/download/os-tmpdir-1.0.2.tgz#bbe67406c79aa85c5cfec766fe5734555dfa1274" 1152 | 1153 | osenv@^0.1.4: 1154 | version "0.1.5" 1155 | resolved "http://registry.npm.taobao.org/osenv/download/osenv-0.1.5.tgz#85cdfafaeb28e8677f416e287592b5f3f49ea410" 1156 | dependencies: 1157 | os-homedir "^1.0.0" 1158 | os-tmpdir "^1.0.0" 1159 | 1160 | output-file-sync@^1.1.2: 1161 | version "1.1.2" 1162 | resolved "http://registry.npm.taobao.org/output-file-sync/download/output-file-sync-1.1.2.tgz#d0a33eefe61a205facb90092e826598d5245ce76" 1163 | dependencies: 1164 | graceful-fs "^4.1.4" 1165 | mkdirp "^0.5.1" 1166 | object-assign "^4.1.0" 1167 | 1168 | parse-glob@^3.0.4: 1169 | version "3.0.4" 1170 | resolved "http://registry.npm.taobao.org/parse-glob/download/parse-glob-3.0.4.tgz#b2c376cfb11f35513badd173ef0bb6e3a388391c" 1171 | dependencies: 1172 | glob-base "^0.3.0" 1173 | is-dotfile "^1.0.0" 1174 | is-extglob "^1.0.0" 1175 | is-glob "^2.0.0" 1176 | 1177 | path-is-absolute@^1.0.0, path-is-absolute@^1.0.1: 1178 | version "1.0.1" 1179 | resolved "http://registry.npm.taobao.org/path-is-absolute/download/path-is-absolute-1.0.1.tgz#174b9268735534ffbc7ace6bf53a5a9e1b5c5f5f" 1180 | 1181 | preserve@^0.2.0: 1182 | version "0.2.0" 1183 | resolved "http://registry.npm.taobao.org/preserve/download/preserve-0.2.0.tgz#815ed1f6ebc65926f865b310c0713bcb3315ce4b" 1184 | 1185 | private@^0.1.6, private@^0.1.8: 1186 | version "0.1.8" 1187 | resolved "http://registry.npm.taobao.org/private/download/private-0.1.8.tgz#2381edb3689f7a53d653190060fcf822d2f368ff" 1188 | 1189 | process-nextick-args@~2.0.0: 1190 | version "2.0.0" 1191 | resolved "http://registry.npm.taobao.org/process-nextick-args/download/process-nextick-args-2.0.0.tgz#a37d732f4271b4ab1ad070d35508e8290788ffaa" 1192 | 1193 | pseudomap@^1.0.2: 1194 | version "1.0.2" 1195 | resolved "http://registry.npm.taobao.org/pseudomap/download/pseudomap-1.0.2.tgz#f052a28da70e618917ef0a8ac34c1ae5a68286b3" 1196 | 1197 | randomatic@^3.0.0: 1198 | version "3.0.0" 1199 | resolved "http://registry.npm.taobao.org/randomatic/download/randomatic-3.0.0.tgz#d35490030eb4f7578de292ce6dfb04a91a128923" 1200 | dependencies: 1201 | is-number "^4.0.0" 1202 | kind-of "^6.0.0" 1203 | math-random "^1.0.1" 1204 | 1205 | rc@^1.1.7: 1206 | version "1.2.7" 1207 | resolved "http://registry.npm.taobao.org/rc/download/rc-1.2.7.tgz#8a10ca30d588d00464360372b890d06dacd02297" 1208 | dependencies: 1209 | deep-extend "^0.5.1" 1210 | ini "~1.3.0" 1211 | minimist "^1.2.0" 1212 | strip-json-comments "~2.0.1" 1213 | 1214 | readable-stream@^2.0.2, readable-stream@^2.0.6: 1215 | version "2.3.6" 1216 | resolved "http://registry.npm.taobao.org/readable-stream/download/readable-stream-2.3.6.tgz#b11c27d88b8ff1fbe070643cf94b0c79ae1b0aaf" 1217 | dependencies: 1218 | core-util-is "~1.0.0" 1219 | inherits "~2.0.3" 1220 | isarray "~1.0.0" 1221 | process-nextick-args "~2.0.0" 1222 | safe-buffer "~5.1.1" 1223 | string_decoder "~1.1.1" 1224 | util-deprecate "~1.0.1" 1225 | 1226 | readdirp@^2.0.0: 1227 | version "2.1.0" 1228 | resolved "http://registry.npm.taobao.org/readdirp/download/readdirp-2.1.0.tgz#4ed0ad060df3073300c48440373f72d1cc642d78" 1229 | dependencies: 1230 | graceful-fs "^4.1.2" 1231 | minimatch "^3.0.2" 1232 | readable-stream "^2.0.2" 1233 | set-immediate-shim "^1.0.1" 1234 | 1235 | regenerate@^1.2.1: 1236 | version "1.4.0" 1237 | resolved "http://registry.npm.taobao.org/regenerate/download/regenerate-1.4.0.tgz#4a856ec4b56e4077c557589cae85e7a4c8869a11" 1238 | 1239 | regenerator-runtime@^0.10.5: 1240 | version "0.10.5" 1241 | resolved "http://registry.npm.taobao.org/regenerator-runtime/download/regenerator-runtime-0.10.5.tgz#336c3efc1220adcedda2c9fab67b5a7955a33658" 1242 | 1243 | regenerator-runtime@^0.11.0: 1244 | version "0.11.1" 1245 | resolved "http://registry.npm.taobao.org/regenerator-runtime/download/regenerator-runtime-0.11.1.tgz#be05ad7f9bf7d22e056f9726cee5017fbf19e2e9" 1246 | 1247 | regenerator-transform@^0.10.0: 1248 | version "0.10.1" 1249 | resolved "http://registry.npm.taobao.org/regenerator-transform/download/regenerator-transform-0.10.1.tgz#1e4996837231da8b7f3cf4114d71b5691a0680dd" 1250 | dependencies: 1251 | babel-runtime "^6.18.0" 1252 | babel-types "^6.19.0" 1253 | private "^0.1.6" 1254 | 1255 | regex-cache@^0.4.2: 1256 | version "0.4.4" 1257 | resolved "http://registry.npm.taobao.org/regex-cache/download/regex-cache-0.4.4.tgz#75bdc58a2a1496cec48a12835bc54c8d562336dd" 1258 | dependencies: 1259 | is-equal-shallow "^0.1.3" 1260 | 1261 | regexpu-core@^2.0.0: 1262 | version "2.0.0" 1263 | resolved "http://registry.npm.taobao.org/regexpu-core/download/regexpu-core-2.0.0.tgz#49d038837b8dcf8bfa5b9a42139938e6ea2ae240" 1264 | dependencies: 1265 | regenerate "^1.2.1" 1266 | regjsgen "^0.2.0" 1267 | regjsparser "^0.1.4" 1268 | 1269 | regjsgen@^0.2.0: 1270 | version "0.2.0" 1271 | resolved "http://registry.npm.taobao.org/regjsgen/download/regjsgen-0.2.0.tgz#6c016adeac554f75823fe37ac05b92d5a4edb1f7" 1272 | 1273 | regjsparser@^0.1.4: 1274 | version "0.1.5" 1275 | resolved "http://registry.npm.taobao.org/regjsparser/download/regjsparser-0.1.5.tgz#7ee8f84dc6fa792d3fd0ae228d24bd949ead205c" 1276 | dependencies: 1277 | jsesc "~0.5.0" 1278 | 1279 | remove-trailing-separator@^1.0.1: 1280 | version "1.1.0" 1281 | resolved "http://registry.npm.taobao.org/remove-trailing-separator/download/remove-trailing-separator-1.1.0.tgz#c24bce2a283adad5bc3f58e0d48249b92379d8ef" 1282 | 1283 | repeat-element@^1.1.2: 1284 | version "1.1.2" 1285 | resolved "http://registry.npm.taobao.org/repeat-element/download/repeat-element-1.1.2.tgz#ef089a178d1483baae4d93eb98b4f9e4e11d990a" 1286 | 1287 | repeat-string@^1.5.2: 1288 | version "1.6.1" 1289 | resolved "http://registry.npm.taobao.org/repeat-string/download/repeat-string-1.6.1.tgz#8dcae470e1c88abc2d600fff4a776286da75e637" 1290 | 1291 | repeating@^2.0.0: 1292 | version "2.0.1" 1293 | resolved "http://registry.npm.taobao.org/repeating/download/repeating-2.0.1.tgz#5214c53a926d3552707527fbab415dbc08d06dda" 1294 | dependencies: 1295 | is-finite "^1.0.0" 1296 | 1297 | rimraf@^2.6.1, rimraf@^2.6.2: 1298 | version "2.6.2" 1299 | resolved "http://registry.npm.taobao.org/rimraf/download/rimraf-2.6.2.tgz#2ed8150d24a16ea8651e6d6ef0f47c4158ce7a36" 1300 | dependencies: 1301 | glob "^7.0.5" 1302 | 1303 | safe-buffer@^5.1.2, safe-buffer@~5.1.0, safe-buffer@~5.1.1: 1304 | version "5.1.2" 1305 | resolved "http://registry.npm.taobao.org/safe-buffer/download/safe-buffer-5.1.2.tgz#991ec69d296e0313747d59bdfd2b745c35f8828d" 1306 | 1307 | "safer-buffer@>= 2.1.2 < 3": 1308 | version "2.1.2" 1309 | resolved "http://registry.npm.taobao.org/safer-buffer/download/safer-buffer-2.1.2.tgz#44fa161b0187b9549dd84bb91802f9bd8385cd6a" 1310 | 1311 | sax@^1.2.4: 1312 | version "1.2.4" 1313 | resolved "http://registry.npm.taobao.org/sax/download/sax-1.2.4.tgz#2816234e2378bddc4e5354fab5caa895df7100d9" 1314 | 1315 | semver@^5.3.0: 1316 | version "5.5.0" 1317 | resolved "http://registry.npm.taobao.org/semver/download/semver-5.5.0.tgz#dc4bbc7a6ca9d916dee5d43516f0092b58f7b8ab" 1318 | 1319 | set-blocking@~2.0.0: 1320 | version "2.0.0" 1321 | resolved "http://registry.npm.taobao.org/set-blocking/download/set-blocking-2.0.0.tgz#045f9782d011ae9a6803ddd382b24392b3d890f7" 1322 | 1323 | set-immediate-shim@^1.0.1: 1324 | version "1.0.1" 1325 | resolved "http://registry.npm.taobao.org/set-immediate-shim/download/set-immediate-shim-1.0.1.tgz#4b2b1b27eb808a9f8dcc481a58e5e56f599f3f61" 1326 | 1327 | shebang-command@^1.2.0: 1328 | version "1.2.0" 1329 | resolved "http://registry.npm.taobao.org/shebang-command/download/shebang-command-1.2.0.tgz#44aac65b695b03398968c39f363fee5deafdf1ea" 1330 | dependencies: 1331 | shebang-regex "^1.0.0" 1332 | 1333 | shebang-regex@^1.0.0: 1334 | version "1.0.0" 1335 | resolved "http://registry.npm.taobao.org/shebang-regex/download/shebang-regex-1.0.0.tgz#da42f49740c0b42db2ca9728571cb190c98efea3" 1336 | 1337 | signal-exit@^3.0.0: 1338 | version "3.0.2" 1339 | resolved "http://registry.npm.taobao.org/signal-exit/download/signal-exit-3.0.2.tgz#b5fdc08f1287ea1178628e415e25132b73646c6d" 1340 | 1341 | slash@^1.0.0: 1342 | version "1.0.0" 1343 | resolved "http://registry.npm.taobao.org/slash/download/slash-1.0.0.tgz#c41f2f6c39fc16d1cd17ad4b5d896114ae470d55" 1344 | 1345 | source-map-support@^0.4.15: 1346 | version "0.4.18" 1347 | resolved "http://registry.npm.taobao.org/source-map-support/download/source-map-support-0.4.18.tgz#0286a6de8be42641338594e97ccea75f0a2c585f" 1348 | dependencies: 1349 | source-map "^0.5.6" 1350 | 1351 | source-map@^0.5.6, source-map@^0.5.7: 1352 | version "0.5.7" 1353 | resolved "http://registry.npm.taobao.org/source-map/download/source-map-0.5.7.tgz#8a039d2d1021d22d1ea14c80d8ea468ba2ef3fcc" 1354 | 1355 | string-width@^1.0.1, string-width@^1.0.2: 1356 | version "1.0.2" 1357 | resolved "http://registry.npm.taobao.org/string-width/download/string-width-1.0.2.tgz#118bdf5b8cdc51a2a7e70d211e07e2b0b9b107d3" 1358 | dependencies: 1359 | code-point-at "^1.0.0" 1360 | is-fullwidth-code-point "^1.0.0" 1361 | strip-ansi "^3.0.0" 1362 | 1363 | string_decoder@~1.1.1: 1364 | version "1.1.1" 1365 | resolved "http://registry.npm.taobao.org/string_decoder/download/string_decoder-1.1.1.tgz#9cf1611ba62685d7030ae9e4ba34149c3af03fc8" 1366 | dependencies: 1367 | safe-buffer "~5.1.0" 1368 | 1369 | strip-ansi@^3.0.0, strip-ansi@^3.0.1: 1370 | version "3.0.1" 1371 | resolved "http://registry.npm.taobao.org/strip-ansi/download/strip-ansi-3.0.1.tgz#6a385fb8853d952d5ff05d0e8aaf94278dc63dcf" 1372 | dependencies: 1373 | ansi-regex "^2.0.0" 1374 | 1375 | strip-json-comments@~2.0.1: 1376 | version "2.0.1" 1377 | resolved "http://registry.npm.taobao.org/strip-json-comments/download/strip-json-comments-2.0.1.tgz#3c531942e908c2697c0ec344858c286c7ca0a60a" 1378 | 1379 | supports-color@^2.0.0: 1380 | version "2.0.0" 1381 | resolved "http://registry.npm.taobao.org/supports-color/download/supports-color-2.0.0.tgz#535d045ce6b6363fa40117084629995e9df324c7" 1382 | 1383 | tar@^4: 1384 | version "4.4.2" 1385 | resolved "http://registry.npm.taobao.org/tar/download/tar-4.4.2.tgz#60685211ba46b38847b1ae7ee1a24d744a2cd462" 1386 | dependencies: 1387 | chownr "^1.0.1" 1388 | fs-minipass "^1.2.5" 1389 | minipass "^2.2.4" 1390 | minizlib "^1.1.0" 1391 | mkdirp "^0.5.0" 1392 | safe-buffer "^5.1.2" 1393 | yallist "^3.0.2" 1394 | 1395 | to-fast-properties@^1.0.3: 1396 | version "1.0.3" 1397 | resolved "http://registry.npm.taobao.org/to-fast-properties/download/to-fast-properties-1.0.3.tgz#b83571fa4d8c25b82e231b06e3a3055de4ca1a47" 1398 | 1399 | trim-right@^1.0.1: 1400 | version "1.0.1" 1401 | resolved "http://registry.npm.taobao.org/trim-right/download/trim-right-1.0.1.tgz#cb2e1203067e0c8de1f614094b9fe45704ea6003" 1402 | 1403 | user-home@^1.1.1: 1404 | version "1.1.1" 1405 | resolved "http://registry.npm.taobao.org/user-home/download/user-home-1.1.1.tgz#2b5be23a32b63a7c9deb8d0f28d485724a3df190" 1406 | 1407 | util-deprecate@~1.0.1: 1408 | version "1.0.2" 1409 | resolved "http://registry.npm.taobao.org/util-deprecate/download/util-deprecate-1.0.2.tgz#450d4dc9fa70de732762fbd2d4a28981419a0ccf" 1410 | 1411 | v8flags@^2.1.1: 1412 | version "2.1.1" 1413 | resolved "http://registry.npm.taobao.org/v8flags/download/v8flags-2.1.1.tgz#aab1a1fa30d45f88dd321148875ac02c0b55e5b4" 1414 | dependencies: 1415 | user-home "^1.1.1" 1416 | 1417 | which@^1.2.9: 1418 | version "1.3.0" 1419 | resolved "http://registry.npm.taobao.org/which/download/which-1.3.0.tgz#ff04bdfc010ee547d780bec38e1ac1c2777d253a" 1420 | dependencies: 1421 | isexe "^2.0.0" 1422 | 1423 | wide-align@^1.1.0: 1424 | version "1.1.2" 1425 | resolved "http://registry.npm.taobao.org/wide-align/download/wide-align-1.1.2.tgz#571e0f1b0604636ebc0dfc21b0339bbe31341710" 1426 | dependencies: 1427 | string-width "^1.0.2" 1428 | 1429 | wrappy@1: 1430 | version "1.0.2" 1431 | resolved "http://registry.npm.taobao.org/wrappy/download/wrappy-1.0.2.tgz#b5243d8f3ec1aa35f1364605bc0d1036e30ab69f" 1432 | 1433 | yallist@^2.1.2: 1434 | version "2.1.2" 1435 | resolved "http://registry.npm.taobao.org/yallist/download/yallist-2.1.2.tgz#1c11f9218f076089a47dd512f93c6699a6a81d52" 1436 | 1437 | yallist@^3.0.0, yallist@^3.0.2: 1438 | version "3.0.2" 1439 | resolved "http://registry.npm.taobao.org/yallist/download/yallist-3.0.2.tgz#8452b4bb7e83c7c188d8041c1a837c773d6d8bb9" 1440 | --------------------------------------------------------------------------------